You've already forked linux-packaging-mono
Imported Upstream version 4.8.0.309
Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
parent
ee1447783b
commit
94b2861243
@@ -63,10 +63,11 @@ namespace System.Activities.Core.Presentation
|
||||
trueLabelText = (string)virtualizingContainer.ModelItem.Properties["TrueLabel"].ComputedValue;
|
||||
}
|
||||
|
||||
double pixelsPerDip = VisualTreeHelper.GetDpi(trueConnectionPoint).PixelsPerDip;
|
||||
actualPoint = new Point(trueConnectionPoint.Location.X - origin.X, trueConnectionPoint.Location.Y - origin.Y);
|
||||
FormattedText trueMarkerFormattedText = new FormattedText(trueLabelText, new System.Globalization.CultureInfo(textCulture),
|
||||
this.FlowDirection, FlowchartDesigner.FlowElementCaptionTypeface, FlowchartDesigner.FlowNodeCaptionFontSize,
|
||||
new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor));
|
||||
new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor), pixelsPerDip);
|
||||
actualPoint.Y += ConnectionPoint.DrawingLargeSide / 2;
|
||||
actualPoint.X -= trueMarkerFormattedText.WidthIncludingTrailingWhitespace;
|
||||
|
||||
@@ -94,9 +95,10 @@ namespace System.Activities.Core.Presentation
|
||||
actualPoint = new Point(falseConnectionPoint.Location.X - origin.X, falseConnectionPoint.Location.Y - origin.Y);
|
||||
actualPoint.Y += ConnectionPoint.DrawingLargeSide / 2;
|
||||
|
||||
double pixelsPerDip = VisualTreeHelper.GetDpi(falseConnectionPoint).PixelsPerDip;
|
||||
FormattedText falseMarkerFormattedText = new FormattedText(falseLabelText, new System.Globalization.CultureInfo(textCulture),
|
||||
this.FlowDirection, FlowchartDesigner.FlowElementCaptionTypeface, FlowchartDesigner.FlowNodeCaptionFontSize,
|
||||
new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor));
|
||||
new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor), pixelsPerDip);
|
||||
|
||||
DrawtWithTransform(
|
||||
drawingContext,
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
using System;
|
||||
using System.Activities;
|
||||
using System.Activities.Debugger;
|
||||
using System.Activities.DynamicUpdate;
|
||||
using System.Activities.Presentation.View;
|
||||
using System.Activities.Presentation.ViewState;
|
||||
using System.Collections.Generic;
|
||||
@@ -30,6 +31,18 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
XamlDebuggerXmlReader.EndColumnName.MemberName
|
||||
};
|
||||
|
||||
// These are used to discover that we have found a DynamicUpdateInfo.OriginalDefintion or OriginalActivityBuilder
|
||||
// attached property member. We have "hardcoded" the *MemberName" here because DynamicUpdateInfo has the
|
||||
// AttachableMemberIdentifier properties marked as private. But the DynamicUpdateInfo class itself is public,
|
||||
// as are the Get and Set methods.
|
||||
static readonly string DynamicUpdateOriginalDefinitionMemberName = "OriginalDefinition";
|
||||
static readonly MethodInfo GetOriginalDefinition = typeof(DynamicUpdateInfo).GetMethod("GetOriginalDefinition");
|
||||
static readonly MethodInfo SetOriginalDefinition = typeof(DynamicUpdateInfo).GetMethod("SetOriginalDefinition");
|
||||
|
||||
static readonly string DynamicUpdateOriginalActivityBuilderMemberName = "OriginalActivityBuilder";
|
||||
static readonly MethodInfo GetOriginalActivityBuilder = typeof(DynamicUpdateInfo).GetMethod("GetOriginalActivityBuilder");
|
||||
static readonly MethodInfo SetOriginalActivityBuilder = typeof(DynamicUpdateInfo).GetMethod("SetOriginalActivityBuilder");
|
||||
|
||||
// This method collects view state attached properties and generates a Xaml node stream
|
||||
// with all view state information appearing within the ViewStateManager node.
|
||||
// It is called when workflow definition is being serialized to string.
|
||||
@@ -279,6 +292,22 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
// Xaml member definition for IdRef. Used to identify existing IdRef properties in the input nodestream.
|
||||
XamlMember idRefMember = new XamlMember(IdRef, GetIdRef, SetIdRef, inputReader.SchemaContext);
|
||||
|
||||
// These are used to ignore the IdRef members that are inside a DynamicUpdateInfo.OriginalDefinition/OriginalActivityBuilder attached property.
|
||||
// We need to ignore these because if we don't, the IdRef values for the objects in the actual workflow defintion will be ignored because of the
|
||||
// duplicate IdRef value. This causes problems with activity designers that depend on the ViewStateManager data to correctly display the workflow
|
||||
// on the WorkflowDesigner canvas.
|
||||
XamlMember originalDefinitionMember = new XamlMember(DynamicUpdateOriginalDefinitionMemberName, GetOriginalDefinition, SetOriginalDefinition, inputReader.SchemaContext);
|
||||
XamlMember originalActivityBuilderMember = new XamlMember(DynamicUpdateOriginalActivityBuilderMemberName, GetOriginalActivityBuilder, SetOriginalActivityBuilder, inputReader.SchemaContext);
|
||||
|
||||
// insideOriginalDefintion gets set to true when we find a "StartMember" node for either of the above two attached properties.
|
||||
// originalDefintionMemberCount gets incremented if we find any "StartMember" and insideOriginalDefinition is true.
|
||||
// originalDefintionMemberCount gets decremented if we find any "EndMember" and insideOriginalDefintion is true.
|
||||
// insideOriginalDefintion gets set to false when we find an "EndMember" and originalDefinitionMemberCount gets decremented to 0.
|
||||
// If insideOriginalDefintion is true when we find an "IdRef" member, we do NOT add that IdRef to the idRefsSeen HashSet to avoid
|
||||
// duplicates being defined by the IdRefs inside of the OriginalDefinition attached properties.
|
||||
bool insideOriginalDefinition = false;
|
||||
int originalDefinitionMemberCount = 0;
|
||||
|
||||
// Dictionary containing Ids and corresponding viewstate related
|
||||
// attached property nodes. Populated by StripViewStateElement method.
|
||||
Dictionary<string, XamlNodeList> viewStateInfo = null;
|
||||
@@ -323,9 +352,21 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
break;
|
||||
|
||||
case XamlNodeType.StartMember:
|
||||
// If we find a StartMember for DynamicUpdateInfo.OriginalDefinition or OriginalActivityBuilder, remember that we are
|
||||
// inside one of those. We don't want to "remember" IdRef values in the idRefsSeen HashSet while inside these attached properties.
|
||||
if (workflowDefinition.Member.Equals(originalDefinitionMember) || workflowDefinition.Member.Equals(originalActivityBuilderMember))
|
||||
{
|
||||
insideOriginalDefinition = true;
|
||||
}
|
||||
|
||||
if (insideOriginalDefinition)
|
||||
{
|
||||
originalDefinitionMemberCount++;
|
||||
}
|
||||
|
||||
// Track when the reader enters IdRef. Skip writing the start
|
||||
// node to the output nodelist until we check for duplicates.
|
||||
if (workflowDefinition.Member.Equals(idRefMember))
|
||||
else if (workflowDefinition.Member.Equals(idRefMember))
|
||||
{
|
||||
inIdRefMember = true;
|
||||
skipWritingWorkflowDefinition = true;
|
||||
@@ -341,38 +382,43 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
case XamlNodeType.Value:
|
||||
if (inIdRefMember)
|
||||
{
|
||||
string idRef = workflowDefinition.Value as string;
|
||||
if (!string.IsNullOrWhiteSpace(idRef))
|
||||
// We don't want to deal with the IdRef if we are inside a DynamicUpdateInfo.OriginalDefinition/OriginalActivityBuilder
|
||||
// attached property.
|
||||
if (!insideOriginalDefinition)
|
||||
{
|
||||
// If IdRef value is a duplicate then do not associate it with
|
||||
// the stack frame (top of stack == activity node with IdRef member on it).
|
||||
if (idRefsSeen.Contains(idRef))
|
||||
string idRef = workflowDefinition.Value as string;
|
||||
if (!string.IsNullOrWhiteSpace(idRef))
|
||||
{
|
||||
stack.Peek().IdRef = null;
|
||||
}
|
||||
// If the IdRef value is unique then associate it with the
|
||||
// stack frame and also write its value into the output nodestream.
|
||||
else
|
||||
{
|
||||
stack.Peek().IdRef = idRef;
|
||||
idManager.UpdateMap(idRef);
|
||||
idRefsSeen.Add(idRef);
|
||||
|
||||
if (shouldPassLineInfo)
|
||||
// If IdRef value is a duplicate then do not associate it with
|
||||
// the stack frame (top of stack == activity node with IdRef member on it).
|
||||
if (idRefsSeen.Contains(idRef))
|
||||
{
|
||||
lineInfoComsumer.SetLineInfo(idRefLineNumber, idRefLinePosition);
|
||||
stack.Peek().IdRef = null;
|
||||
}
|
||||
|
||||
mergedNodeWriter.WriteStartMember(idRefMember);
|
||||
|
||||
if (shouldPassLineInfo)
|
||||
// If the IdRef value is unique then associate it with the
|
||||
// stack frame and also write its value into the output nodestream.
|
||||
else
|
||||
{
|
||||
lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
|
||||
stack.Peek().IdRef = idRef;
|
||||
idManager.UpdateMap(idRef);
|
||||
idRefsSeen.Add(idRef);
|
||||
|
||||
if (shouldPassLineInfo)
|
||||
{
|
||||
lineInfoComsumer.SetLineInfo(idRefLineNumber, idRefLinePosition);
|
||||
}
|
||||
|
||||
mergedNodeWriter.WriteStartMember(idRefMember);
|
||||
|
||||
if (shouldPassLineInfo)
|
||||
{
|
||||
lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
|
||||
}
|
||||
|
||||
mergedNodeWriter.WriteValue(idRef);
|
||||
|
||||
shouldWriteIdRefEndMember = true;
|
||||
}
|
||||
|
||||
mergedNodeWriter.WriteValue(idRef);
|
||||
|
||||
shouldWriteIdRefEndMember = true;
|
||||
}
|
||||
}
|
||||
// Don't need to write IdRef value into the output
|
||||
@@ -382,9 +428,21 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
break;
|
||||
|
||||
case XamlNodeType.EndMember:
|
||||
// If we are inside an OriginalDefinition/OriginalActivityBuilder attached property,
|
||||
// decrement the count and if it goes to zero, set insideOriginalDefintion to false
|
||||
// because we just encountered the EndMember for it.
|
||||
if (insideOriginalDefinition)
|
||||
{
|
||||
originalDefinitionMemberCount--;
|
||||
if (originalDefinitionMemberCount == 0)
|
||||
{
|
||||
insideOriginalDefinition = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Exit IdRef node. Skip writing the EndMember node, we would have done
|
||||
// it as part of reading the IdRef value.
|
||||
if (inIdRefMember)
|
||||
if (inIdRefMember && !insideOriginalDefinition)
|
||||
{
|
||||
inIdRefMember = false;
|
||||
skipWritingWorkflowDefinition = true;
|
||||
@@ -401,6 +459,7 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
mergedNodeWriter.WriteEndMember();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case XamlNodeType.EndObject:
|
||||
@@ -592,6 +651,7 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
viewStateSourceLocationMap = null;
|
||||
XamlNodeList strippedNodeList = new XamlNodeList(inputReader.SchemaContext);
|
||||
XamlMember viewStateManager = new XamlMember(ViewStateManager, GetViewStateManager, SetViewStateManager, inputReader.SchemaContext);
|
||||
|
||||
using (XamlWriter strippedWriter = strippedNodeList.Writer)
|
||||
{
|
||||
IXamlLineInfo lineInfo = inputReader as IXamlLineInfo;
|
||||
@@ -618,7 +678,7 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
|
||||
return strippedNodeList.GetReader();
|
||||
}
|
||||
|
||||
|
||||
// This method reads ViewStateManager nodes from the xaml nodestream and outputs that in the
|
||||
// viewStateInfo dictionary. The input reader is positioned on the ViewStateManagerNode in the nodestream.
|
||||
static void ReadViewStateInfo(XamlReader inputReader, out Dictionary<string, XamlNodeList> viewStateInfo, out Dictionary<string, SourceLocation> viewStateSourceLocationMap)
|
||||
@@ -700,7 +760,11 @@ namespace Microsoft.Activities.Presentation.Xaml
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (globalMemberLevel == 1 && !IsAttachablePropertyForConvert(xamlReader))
|
||||
// The xamlReader.ReadSubtree and subsequent while loop to get the Id member
|
||||
// has moved the xamlReader forward to the next member. We need to check to see
|
||||
// if it is an Attached Property that we care about. If it isn't then we need to
|
||||
// skip it and not put it in the resulting XamlNodeList.
|
||||
if (globalMemberLevel == 1 && !IsAttachablePropertyForConvert(xamlReader))
|
||||
{
|
||||
skippingUnexpectedAttachedProperty = true;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,20 @@ namespace System.Activities.Hosting
|
||||
StackTrace abortStack;
|
||||
#endif
|
||||
|
||||
static WorkflowInstance()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (TelemetryEventSource eventSource = new TelemetryEventSource())
|
||||
{
|
||||
eventSource.V2Runtime();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected WorkflowInstance(Activity workflowDefinition)
|
||||
: this(workflowDefinition, null)
|
||||
{
|
||||
|
||||
@@ -1 +1 @@
|
||||
2090063250746eae0b7a6eaec193aac86984b785
|
||||
ff9b74d7295d3a52cf91057ee647d184edec0c5e
|
||||
@@ -21,8 +21,10 @@ namespace System.ComponentModel.DataAnnotations {
|
||||
}
|
||||
|
||||
public static void SetDefaultsLessOrEqual_46() {
|
||||
#pragma warning disable BCL0012 //disable warning about AppContextDefaults not following the recommended pattern
|
||||
// Define the switches that should be true for 4.6 or less, false for 4.6.1+.
|
||||
LocalAppContext.DefineSwitchDefault(UseLegacyRegExTimeoutString, true);
|
||||
#pragma warning restore BCL0012
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.ComponentModel.DataAnnotations.Resources;
|
||||
using System.ComponentModel.DataAnnotations.Resources;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -19,7 +19,18 @@ namespace System.ComponentModel.DataAnnotations {
|
||||
/// Gets or sets the timeout to use when matching the regular expression pattern (in milliseconds)
|
||||
/// (-1 means never timeout).
|
||||
/// </summary>
|
||||
public int MatchTimeoutInMilliseconds { get; set; } = GetDefaultTimeout();
|
||||
public int MatchTimeoutInMilliseconds {
|
||||
get {
|
||||
return _matchTimeoutInMilliseconds;
|
||||
}
|
||||
set {
|
||||
_matchTimeoutInMilliseconds = value;
|
||||
_matchTimeoutSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
private int _matchTimeoutInMilliseconds;
|
||||
private bool _matchTimeoutSet;
|
||||
|
||||
private Regex Regex { get; set; }
|
||||
|
||||
@@ -90,6 +101,11 @@ namespace System.ComponentModel.DataAnnotations {
|
||||
if (string.IsNullOrEmpty(this.Pattern)) {
|
||||
throw new InvalidOperationException(DataAnnotationsResources.RegularExpressionAttribute_Empty_Pattern);
|
||||
}
|
||||
|
||||
if (!_matchTimeoutSet) {
|
||||
MatchTimeoutInMilliseconds = GetDefaultTimeout();
|
||||
}
|
||||
|
||||
Regex = MatchTimeoutInMilliseconds == -1
|
||||
? new Regex(Pattern)
|
||||
: Regex = new Regex(Pattern, default(RegexOptions), TimeSpan.FromMilliseconds((double)MatchTimeoutInMilliseconds));
|
||||
|
||||
@@ -3,6 +3,15 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
// There are cases where we have multiple assemblies that are going to import this file and
|
||||
// if they are going to also have InternalsVisibleTo between them, there will be a compiler warning
|
||||
// that the type is found both in the source and in a referenced assembly. The compiler will prefer
|
||||
// the version of the type defined in the source
|
||||
//
|
||||
// In order to disable the warning for this type we are disabling this warning for this entire file.
|
||||
#pragma warning disable 436
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -167,3 +176,5 @@ namespace System
|
||||
static partial void PopulateDefaultValuesPartial(string platformIdentifier, string profile, int version);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore 436
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
//
|
||||
// ==--==
|
||||
|
||||
// There are cases where we have multiple assemblies that are going to import this file and
|
||||
// if they are going to also have InternalsVisibleTo between them, there will be a compiler warning
|
||||
// that the type is found both in the source and in a referenced assembly. The compiler will prefer
|
||||
// the version of the type defined in the source
|
||||
//
|
||||
// In order to disable the warning for this type we are disabling this warning for this entire file.
|
||||
#pragma warning disable 436
|
||||
|
||||
// NOTE: This file should not be included in mscorlib. This should only be included in FX libraries that need to provide switches
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -126,3 +134,5 @@ namespace System
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore 436
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace System.Configuration {
|
||||
const string ClickOnceDataDirectory = "DataDirectory";
|
||||
const string ConfigExtension = ".config";
|
||||
const int MAX_PATH = 260;
|
||||
const int MAX_UNICODESTRING_LEN = short.MaxValue;
|
||||
const int ERROR_INSUFFICIENT_BUFFER = 122; //https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
|
||||
const int MAX_LENGTH_TO_USE = 25;
|
||||
const string FILE_URI_LOCAL = "file:///";
|
||||
const string FILE_URI_UNC = "file://";
|
||||
@@ -108,7 +110,18 @@ namespace System.Configuration {
|
||||
}
|
||||
else {
|
||||
StringBuilder sb = new StringBuilder(MAX_PATH);
|
||||
UnsafeNativeMethods.GetModuleFileName(new HandleRef(null, IntPtr.Zero), sb, sb.Capacity);
|
||||
int noOfTimes = 1;
|
||||
int length = 0;
|
||||
// Iterating by allocating chunk of memory each time we find the length is not sufficient.
|
||||
// Performance should not be an issue for current MAX_PATH length due to this change.
|
||||
while (((length = UnsafeNativeMethods.GetModuleFileName(new HandleRef(null, IntPtr.Zero), sb, sb.Capacity)) == sb.Capacity)
|
||||
&& Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER
|
||||
&& sb.Capacity < MAX_UNICODESTRING_LEN) {
|
||||
noOfTimes += 2; // increasing buffer size by 520 in each iteration - perf.
|
||||
int capacity = noOfTimes * MAX_PATH < MAX_UNICODESTRING_LEN ? noOfTimes * MAX_PATH : MAX_UNICODESTRING_LEN;
|
||||
sb.EnsureCapacity(capacity);
|
||||
}
|
||||
sb.Length = length;
|
||||
applicationUri = Path.GetFullPath(sb.ToString());
|
||||
applicationFilename = applicationUri;
|
||||
}
|
||||
|
||||
@@ -186,6 +186,8 @@ namespace Microsoft.Win32.SafeHandles {
|
||||
#pragma warning restore 618
|
||||
#endif
|
||||
internal sealed class SafeCapiHashHandle : SafeCapiHandleBase {
|
||||
private static volatile SafeCapiHashHandle s_invalidHandle;
|
||||
|
||||
#if FEATURE_CORESYSTEM
|
||||
[System.Security.SecurityCritical]
|
||||
#endif
|
||||
@@ -197,9 +199,17 @@ namespace Microsoft.Win32.SafeHandles {
|
||||
/// </summary>
|
||||
public static SafeCapiHashHandle InvalidHandle {
|
||||
get {
|
||||
SafeCapiHashHandle handle = new SafeCapiHashHandle();
|
||||
handle.SetHandle(IntPtr.Zero);
|
||||
return handle;
|
||||
if (s_invalidHandle == null) {
|
||||
// More than one of these might get created in parallel, but that's okay.
|
||||
// Saving one to the field saves on GC tracking, but by SuppressingFinalize on
|
||||
// any instance returned there's already less finalization pressure.
|
||||
SafeCapiHashHandle handle = new SafeCapiHashHandle();
|
||||
handle.SetHandle(IntPtr.Zero);
|
||||
GC.SuppressFinalize(handle);
|
||||
s_invalidHandle = handle;
|
||||
}
|
||||
|
||||
return s_invalidHandle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,6 +243,8 @@ namespace Microsoft.Win32.SafeHandles {
|
||||
#pragma warning restore 618
|
||||
#endif
|
||||
internal sealed class SafeCapiKeyHandle : SafeCapiHandleBase {
|
||||
private static volatile SafeCapiKeyHandle s_invalidHandle;
|
||||
|
||||
#if FEATURE_CORESYSTEM
|
||||
[System.Security.SecurityCritical]
|
||||
#endif
|
||||
@@ -245,9 +257,17 @@ namespace Microsoft.Win32.SafeHandles {
|
||||
internal static SafeCapiKeyHandle InvalidHandle {
|
||||
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
|
||||
get {
|
||||
SafeCapiKeyHandle handle = new SafeCapiKeyHandle();
|
||||
handle.SetHandle(IntPtr.Zero);
|
||||
return handle;
|
||||
if (s_invalidHandle == null) {
|
||||
// More than one of these might get created in parallel, but that's okay.
|
||||
// Saving one to the field saves on GC tracking, but by SuppressingFinalize on
|
||||
// any instance returned there's already less finalization pressure.
|
||||
SafeCapiKeyHandle handle = new SafeCapiKeyHandle();
|
||||
handle.SetHandle(IntPtr.Zero);
|
||||
GC.SuppressFinalize(handle);
|
||||
s_invalidHandle = handle;
|
||||
}
|
||||
|
||||
return s_invalidHandle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,35 @@ namespace System.Security.Cryptography {
|
||||
/// </summary>
|
||||
Pss = 8 // BCRYPT_PAD_PSS
|
||||
}
|
||||
#if !MONO
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct BCRYPT_DSA_KEY_BLOB_V2
|
||||
{
|
||||
public BCryptNative.KeyBlobMagicNumber dwMagic; // BCRYPT_DSA_PUBLIC_MAGIC_V2 or BCRYPT_DSA_PRIVATE_MAGIC_V2
|
||||
public int cbKey; // key lengths in BYTES (e.g. for a 3072-bit key, cbKey = 3072/8 = 384)
|
||||
public HASHALGORITHM_ENUM hashAlgorithm;
|
||||
public DSAFIPSVERSION_ENUM standardVersion;
|
||||
public int cbSeedLength; // size (in bytes) of the seed value
|
||||
public int cbGroupSize; // size (in bytes) of the Q value
|
||||
public byte Count3; // # of iterations used to generate Q. In big-endian format.
|
||||
public byte Count2;
|
||||
public byte Count1;
|
||||
public byte Count0;
|
||||
}
|
||||
#endif
|
||||
internal enum HASHALGORITHM_ENUM : int
|
||||
{
|
||||
DSA_HASH_ALGORITHM_SHA1 = 0,
|
||||
DSA_HASH_ALGORITHM_SHA256 = 1,
|
||||
DSA_HASH_ALGORITHM_SHA512 = 2,
|
||||
}
|
||||
|
||||
internal enum DSAFIPSVERSION_ENUM : int
|
||||
{
|
||||
DSA_FIPS186_2 = 0,
|
||||
DSA_FIPS186_3 = 1,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Native interop with CNG's BCrypt layer. Native definitions can be found in bcrypt.h
|
||||
/// </summary>
|
||||
@@ -102,6 +131,10 @@ namespace System.Security.Cryptography {
|
||||
/// Magic numbers identifying blob types
|
||||
/// </summary>
|
||||
internal enum KeyBlobMagicNumber {
|
||||
DsaPublic = 0x42505344, // BCRYPT_DSA_PUBLIC_MAGIC for key lengths <= 1024 bits
|
||||
DsaPublicV2 = 0x32425044, // BCRYPT_DSA_PUBLIC_MAGIC_V2 for key lengths > 1024 bits
|
||||
DsaPrivate = 0x56505344, // BCRYPT_DSA_PRIVATE_MAGIC for key lengths <= 1024 bits
|
||||
DsaPrivateV2 = 0x32565044, // BCRYPT_DSA_PRIVATE_MAGIC_V2 for key lengths > 1024 bits
|
||||
ECDHPublicP256 = 0x314B4345, // BCRYPT_ECDH_PUBLIC_P256_MAGIC
|
||||
ECDHPublicP384 = 0x334B4345, // BCRYPT_ECDH_PUBLIC_P384_MAGIC
|
||||
ECDHPublicP521 = 0x354B4345, // BCRYPT_ECDH_PUBLIC_P521_MAGIC
|
||||
|
||||
@@ -168,6 +168,14 @@ namespace System.Security.Cryptography {
|
||||
public IntPtr pbData;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CERT_DSS_PARAMETERS
|
||||
{
|
||||
public CRYPTOAPI_BLOB p;
|
||||
public CRYPTOAPI_BLOB q;
|
||||
public CRYPTOAPI_BLOB g;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe struct PROV_ENUMALGS {
|
||||
public AlgorithmId aiAlgId;
|
||||
@@ -187,6 +195,8 @@ namespace System.Security.Cryptography {
|
||||
internal const uint CALG_DSS_SIGN = (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY);
|
||||
internal const uint CALG_RSA_KEYX = (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | ALG_SID_RSA_ANY);
|
||||
internal const uint CNG_RSA_PUBLIC_KEY_BLOB = 72;
|
||||
internal const uint X509_DSS_PUBLICKEY = 38;
|
||||
internal const uint X509_DSS_PARAMETERS = 39;
|
||||
|
||||
internal const uint X509_ASN_ENCODING = 0x00000001;
|
||||
internal const uint PKCS_7_ASN_ENCODING = 0x00010000;
|
||||
|
||||
@@ -447,6 +447,9 @@ namespace System.Security.Cryptography {
|
||||
buffer.Length);
|
||||
}
|
||||
else {
|
||||
if (!LocalAppContextSwitches.AesCryptoServiceProviderDontCorrectlyResetDecryptor) {
|
||||
resetSize = buffer.Length;
|
||||
}
|
||||
CapiNative.UnsafeNativeMethods.CryptDecrypt(m_key,
|
||||
SafeCapiHashHandle.InvalidHandle,
|
||||
true,
|
||||
|
||||
@@ -46,6 +46,101 @@ namespace System.Security.Cryptography {
|
||||
//
|
||||
|
||||
public abstract ECDiffieHellmanPublicKey PublicKey { get; }
|
||||
public abstract byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey);
|
||||
|
||||
// This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract.
|
||||
public virtual byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey)
|
||||
{
|
||||
throw DerivedClassMustOverride();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derive key material using the formula HASH(x) where x is the computed result of the EC Diffie-Hellman algorithm.
|
||||
/// </summary>
|
||||
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
|
||||
/// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
|
||||
/// <returns>A hashed output suitable for key material</returns>
|
||||
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
|
||||
public byte[] DeriveKeyFromHash(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm)
|
||||
{
|
||||
return DeriveKeyFromHash(otherPartyPublicKey, hashAlgorithm, null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derive key material using the formula HASH(secretPrepend || x || secretAppend) where x is the computed
|
||||
/// result of the EC Diffie-Hellman algorithm.
|
||||
/// </summary>
|
||||
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
|
||||
/// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
|
||||
/// <param name="secretPrepend">A value to prepend to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
|
||||
/// <param name="secretAppend">A value to append to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
|
||||
/// <returns>A hashed output suitable for key material</returns>
|
||||
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
|
||||
public virtual byte[] DeriveKeyFromHash(
|
||||
ECDiffieHellmanPublicKey otherPartyPublicKey,
|
||||
HashAlgorithmName hashAlgorithm,
|
||||
byte[] secretPrepend,
|
||||
byte[] secretAppend)
|
||||
{
|
||||
throw DerivedClassMustOverride();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derive key material using the formula HMAC(hmacKey, x) where x is the computed
|
||||
/// result of the EC Diffie-Hellman algorithm.
|
||||
/// </summary>
|
||||
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
|
||||
/// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
|
||||
/// <param name="hmacKey">The key to use in the HMAC. A <c>null</c> value indicates that the result of the EC Diffie-Hellman algorithm should be used as the HMAC key.</param>
|
||||
/// <returns>A hashed output suitable for key material</returns>
|
||||
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
|
||||
public byte[] DeriveKeyFromHmac(
|
||||
ECDiffieHellmanPublicKey otherPartyPublicKey,
|
||||
HashAlgorithmName hashAlgorithm,
|
||||
byte[] hmacKey)
|
||||
{
|
||||
return DeriveKeyFromHmac(otherPartyPublicKey, hashAlgorithm, hmacKey, null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derive key material using the formula HMAC(hmacKey, secretPrepend || x || secretAppend) where x is the computed
|
||||
/// result of the EC Diffie-Hellman algorithm.
|
||||
/// </summary>
|
||||
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
|
||||
/// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
|
||||
/// <param name="hmacKey">The key to use in the HMAC. A <c>null</c> value indicates that the result of the EC Diffie-Hellman algorithm should be used as the HMAC key.</param>
|
||||
/// <param name="secretPrepend">A value to prepend to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
|
||||
/// <param name="secretAppend">A value to append to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
|
||||
/// <returns>A hashed output suitable for key material</returns>
|
||||
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
|
||||
public virtual byte[] DeriveKeyFromHmac(
|
||||
ECDiffieHellmanPublicKey otherPartyPublicKey,
|
||||
HashAlgorithmName hashAlgorithm,
|
||||
byte[] hmacKey,
|
||||
byte[] secretPrepend,
|
||||
byte[] secretAppend)
|
||||
{
|
||||
throw DerivedClassMustOverride();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derive key material using the TLS pseudo-random function (PRF) derivation algorithm.
|
||||
/// </summary>
|
||||
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
|
||||
/// <param name="prfLabel">The ASCII encoded PRF label.</param>
|
||||
/// <param name="prfSeed">The 64-byte PRF seed.</param>
|
||||
/// <returns>A 48-byte output of the TLS pseudo-random function.</returns>
|
||||
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="prfLabel"/> is null</exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="prfSeed"/> is null</exception>
|
||||
/// <exception cref="CryptographicException"><paramref name="prfSeed"/> is not exactly 64 bytes in length</exception>
|
||||
public virtual byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed)
|
||||
{
|
||||
throw DerivedClassMustOverride();
|
||||
}
|
||||
|
||||
private static Exception DerivedClassMustOverride()
|
||||
{
|
||||
return new NotImplementedException(SR.GetString(SR.NotSupported_SubclassOverride));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,21 @@ namespace System.Security.Cryptography {
|
||||
}
|
||||
CodeAccessPermission.RevertAssert();
|
||||
|
||||
KeySize = m_key.KeySize;
|
||||
// Our LegalKeySizes value stores the values that we encoded as being the correct
|
||||
// legal key size limitations for this algorithm, as documented on MSDN.
|
||||
//
|
||||
// But on a new OS version we might not question if our limit is accurate, or MSDN
|
||||
// could have been innacurate to start with.
|
||||
//
|
||||
// Since the key is already loaded, we know that Windows thought it to be valid;
|
||||
// therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance
|
||||
// check.
|
||||
//
|
||||
// For RSA there are known cases where this change matters. RSACryptoServiceProvider can
|
||||
// create a 384-bit RSA key, which we consider too small to be legal. It can also create
|
||||
// a 1032-bit RSA key, which we consider illegal because it doesn't match our 64-bit
|
||||
// alignment requirement. (In both cases Windows loads it just fine)
|
||||
KeySizeValue = m_key.KeySize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -247,7 +261,22 @@ namespace System.Security.Cryptography {
|
||||
//
|
||||
|
||||
m_key = value;
|
||||
KeySize = m_key.KeySize;
|
||||
|
||||
// Our LegalKeySizes value stores the values that we encoded as being the correct
|
||||
// legal key size limitations for this algorithm, as documented on MSDN.
|
||||
//
|
||||
// But on a new OS version we might not question if our limit is accurate, or MSDN
|
||||
// could have been innacurate to start with.
|
||||
//
|
||||
// Since the key is already loaded, we know that Windows thought it to be valid;
|
||||
// therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance
|
||||
// check.
|
||||
//
|
||||
// For RSA there are known cases where this change matters. RSACryptoServiceProvider can
|
||||
// create a 384-bit RSA key, which we consider too small to be legal. It can also create
|
||||
// a 1032-bit RSA key, which we consider illegal because it doesn't match our 64-bit
|
||||
// alignment requirement. (In both cases Windows loads it just fine)
|
||||
KeySizeValue = m_key.KeySize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,6 +398,84 @@ namespace System.Security.Cryptography {
|
||||
}
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
public override byte[] DeriveKeyFromHash(
|
||||
ECDiffieHellmanPublicKey otherPartyPublicKey,
|
||||
HashAlgorithmName hashAlgorithm,
|
||||
byte[] secretPrepend,
|
||||
byte[] secretAppend)
|
||||
{
|
||||
Contract.Ensures(Contract.Result<byte[]>() != null);
|
||||
|
||||
if (otherPartyPublicKey == null)
|
||||
throw new ArgumentNullException("otherPartyPublicKey");
|
||||
if (string.IsNullOrEmpty(hashAlgorithm.Name))
|
||||
throw new ArgumentException(SR.GetString(SR.Cryptography_HashAlgorithmNameNullOrEmpty), "hashAlgorithm");
|
||||
|
||||
using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey))
|
||||
{
|
||||
return NCryptNative.DeriveKeyMaterialHash(
|
||||
secretAgreement,
|
||||
hashAlgorithm.Name,
|
||||
secretPrepend,
|
||||
secretAppend,
|
||||
NCryptNative.SecretAgreementFlags.None);
|
||||
}
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
public override byte[] DeriveKeyFromHmac(
|
||||
ECDiffieHellmanPublicKey otherPartyPublicKey,
|
||||
HashAlgorithmName hashAlgorithm,
|
||||
byte[] hmacKey,
|
||||
byte[] secretPrepend,
|
||||
byte[] secretAppend)
|
||||
{
|
||||
Contract.Ensures(Contract.Result<byte[]>() != null);
|
||||
|
||||
if (otherPartyPublicKey == null)
|
||||
throw new ArgumentNullException("otherPartyPublicKey");
|
||||
if (string.IsNullOrEmpty(hashAlgorithm.Name))
|
||||
throw new ArgumentException(SR.GetString(SR.Cryptography_HashAlgorithmNameNullOrEmpty), "hashAlgorithm");
|
||||
|
||||
using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey))
|
||||
{
|
||||
NCryptNative.SecretAgreementFlags flags = hmacKey == null ?
|
||||
NCryptNative.SecretAgreementFlags.UseSecretAsHmacKey :
|
||||
NCryptNative.SecretAgreementFlags.None;
|
||||
|
||||
return NCryptNative.DeriveKeyMaterialHmac(
|
||||
secretAgreement,
|
||||
hashAlgorithm.Name,
|
||||
hmacKey,
|
||||
secretPrepend,
|
||||
secretAppend,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
public override byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed)
|
||||
{
|
||||
Contract.Ensures(Contract.Result<byte[]>() != null);
|
||||
|
||||
if (otherPartyPublicKey == null)
|
||||
throw new ArgumentNullException("otherPartyPublicKey");
|
||||
if (prfLabel == null)
|
||||
throw new ArgumentNullException("prfLabel");
|
||||
if (prfSeed == null)
|
||||
throw new ArgumentNullException("prfSeed");
|
||||
|
||||
using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey))
|
||||
{
|
||||
return NCryptNative.DeriveKeyMaterialTls(
|
||||
secretAgreement,
|
||||
prfLabel,
|
||||
prfSeed,
|
||||
NCryptNative.SecretAgreementFlags.None);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a handle to the secret agreement generated between two parties
|
||||
/// </summary>
|
||||
|
||||
@@ -40,6 +40,10 @@ namespace System.Security.Cryptography {
|
||||
return m_keyBlob.Clone() as byte[];
|
||||
}
|
||||
|
||||
public abstract string ToXmlString();
|
||||
// This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract.
|
||||
public virtual string ToXmlString()
|
||||
{
|
||||
throw new NotImplementedException(SR.GetString(SR.NotSupported_SubclassOverride));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,12 +82,12 @@ namespace System.Security.Cryptography {
|
||||
[SecuritySafeCritical]
|
||||
public ECDsaCng(CngKey key) {
|
||||
Contract.Ensures(LegalKeySizesValue != null);
|
||||
Contract.Ensures(m_key != null && m_key.AlgorithmGroup == CngAlgorithmGroup.ECDsa);
|
||||
Contract.Ensures(m_key != null && IsEccAlgorithmGroup(m_key.AlgorithmGroup));
|
||||
|
||||
if (key == null) {
|
||||
throw new ArgumentNullException("key");
|
||||
}
|
||||
if (key.AlgorithmGroup != CngAlgorithmGroup.ECDsa) {
|
||||
if (!IsEccAlgorithmGroup(key.AlgorithmGroup)) {
|
||||
throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDsaRequiresECDsaKey), "key");
|
||||
}
|
||||
|
||||
@@ -111,7 +111,21 @@ namespace System.Security.Cryptography {
|
||||
}
|
||||
CodeAccessPermission.RevertAssert();
|
||||
|
||||
KeySize = m_key.KeySize;
|
||||
// Our LegalKeySizes value stores the values that we encoded as being the correct
|
||||
// legal key size limitations for this algorithm, as documented on MSDN.
|
||||
//
|
||||
// But on a new OS version we might not question if our limit is accurate, or MSDN
|
||||
// could have been innacurate to start with.
|
||||
//
|
||||
// Since the key is already loaded, we know that Windows thought it to be valid;
|
||||
// therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance
|
||||
// check.
|
||||
//
|
||||
// For RSA there are known cases where this change matters. RSACryptoServiceProvider can
|
||||
// create a 384-bit RSA key, which we consider too small to be legal. It can also create
|
||||
// a 1032-bit RSA key, which we consider illegal because it doesn't match our 64-bit
|
||||
// alignment requirement. (In both cases Windows loads it just fine)
|
||||
KeySizeValue = m_key.KeySize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -140,8 +154,8 @@ namespace System.Security.Cryptography {
|
||||
public CngKey Key {
|
||||
get {
|
||||
Contract.Ensures(Contract.Result<CngKey>() != null);
|
||||
Contract.Ensures(Contract.Result<CngKey>().AlgorithmGroup == CngAlgorithmGroup.ECDsa);
|
||||
Contract.Ensures(m_key != null && m_key.AlgorithmGroup == CngAlgorithmGroup.ECDsa);
|
||||
Contract.Ensures(IsEccAlgorithmGroup(Contract.Result<CngKey>().AlgorithmGroup));
|
||||
Contract.Ensures(m_key != null && IsEccAlgorithmGroup(m_key.AlgorithmGroup));
|
||||
|
||||
// If the size of the key no longer matches our stored value, then we need to replace it with
|
||||
// a new key of the correct size.
|
||||
@@ -179,9 +193,9 @@ namespace System.Security.Cryptography {
|
||||
|
||||
private set {
|
||||
Contract.Requires(value != null);
|
||||
Contract.Ensures(m_key != null && m_key.AlgorithmGroup == CngAlgorithmGroup.ECDsa);
|
||||
Contract.Ensures(m_key != null && IsEccAlgorithmGroup(m_key.AlgorithmGroup));
|
||||
|
||||
if (value.AlgorithmGroup != CngAlgorithmGroup.ECDsa) {
|
||||
if (!IsEccAlgorithmGroup(value.AlgorithmGroup)) {
|
||||
throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDsaRequiresECDsaKey));
|
||||
}
|
||||
|
||||
@@ -196,7 +210,22 @@ namespace System.Security.Cryptography {
|
||||
//
|
||||
|
||||
m_key = value;
|
||||
KeySize = m_key.KeySize;
|
||||
|
||||
// Our LegalKeySizes value stores the values that we encoded as being the correct
|
||||
// legal key size limitations for this algorithm, as documented on MSDN.
|
||||
//
|
||||
// But on a new OS version we might not question if our limit is accurate, or MSDN
|
||||
// could have been innacurate to start with.
|
||||
//
|
||||
// Since the key is already loaded, we know that Windows thought it to be valid;
|
||||
// therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance
|
||||
// check.
|
||||
//
|
||||
// For RSA there are known cases where this change matters. RSACryptoServiceProvider can
|
||||
// create a 384-bit RSA key, which we consider too small to be legal. It can also create
|
||||
// a 1032-bit RSA key, which we consider illegal because it doesn't match our 64-bit
|
||||
// alignment requirement. (In both cases Windows loads it just fine)
|
||||
KeySizeValue = m_key.KeySize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,6 +473,16 @@ namespace System.Security.Cryptography {
|
||||
return hasher.HashFinal();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private static bool IsEccAlgorithmGroup(CngAlgorithmGroup algorithmGroup)
|
||||
{
|
||||
// Sometimes, when reading from certificates, ECDSA keys get identified as ECDH.
|
||||
// Windows allows the ECDH keys to perform both key exchange (ECDH) and signing (ECDSA),
|
||||
// so either value is acceptable for the ECDSA wrapper object.
|
||||
//
|
||||
// It is worth noting, however, that ECDSA-identified keys cannot be used for key exchange (ECDH) in CNG.
|
||||
return algorithmGroup == CngAlgorithmGroup.ECDsa || algorithmGroup == CngAlgorithmGroup.ECDiffieHellman;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,10 +796,6 @@ namespace System.Security.Cryptography {
|
||||
signature,
|
||||
signature.Length,
|
||||
paddingMode);
|
||||
if (error != ErrorCode.Success && error != ErrorCode.BadSignature) {
|
||||
throw new CryptographicException((int)error);
|
||||
}
|
||||
|
||||
return error == ErrorCode.Success;
|
||||
}
|
||||
|
||||
@@ -1694,6 +1690,55 @@ namespace System.Security.Cryptography {
|
||||
return signature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sign a hash using no padding
|
||||
/// </summary>
|
||||
[System.Security.SecurityCritical]
|
||||
internal static byte[] SignHash(SafeNCryptKeyHandle key, byte[] hash, int expectedSize)
|
||||
{
|
||||
Contract.Requires(key != null);
|
||||
Contract.Requires(hash != null);
|
||||
Contract.Ensures(Contract.Result<byte[]>() != null);
|
||||
|
||||
#if DEBUG
|
||||
expectedSize = 1;
|
||||
#endif
|
||||
|
||||
// Figure out how big the signature is
|
||||
byte[] signature = new byte[expectedSize];
|
||||
int signatureSize = 0;
|
||||
ErrorCode error = UnsafeNativeMethods.NCryptSignHash(key,
|
||||
IntPtr.Zero,
|
||||
hash,
|
||||
hash.Length,
|
||||
signature,
|
||||
signature.Length,
|
||||
out signatureSize,
|
||||
0);
|
||||
|
||||
if (error == ErrorCode.BufferTooSmall)
|
||||
{
|
||||
signature = new byte[signatureSize];
|
||||
|
||||
error = UnsafeNativeMethods.NCryptSignHash(key,
|
||||
IntPtr.Zero,
|
||||
hash,
|
||||
hash.Length,
|
||||
signature,
|
||||
signature.Length,
|
||||
out signatureSize,
|
||||
0);
|
||||
}
|
||||
|
||||
if (error != ErrorCode.Success)
|
||||
{
|
||||
throw new CryptographicException((int)error);
|
||||
}
|
||||
|
||||
Array.Resize(ref signature, signatureSize);
|
||||
return signature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpack a key blob in ECC public blob format into its X and Y parameters
|
||||
///
|
||||
@@ -1736,10 +1781,6 @@ namespace System.Security.Cryptography {
|
||||
signature.Length,
|
||||
0);
|
||||
|
||||
if (error != ErrorCode.Success && error != ErrorCode.BadSignature) {
|
||||
throw new CryptographicException((int)error);
|
||||
}
|
||||
|
||||
return error == ErrorCode.Success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,11 @@ namespace System.Security.Cryptography
|
||||
// If we don't have a key yet, we need to generate a random one now
|
||||
if (_key == null)
|
||||
{
|
||||
CngKeyCreationParameters creationParameters = new CngKeyCreationParameters();
|
||||
CngKeyCreationParameters creationParameters = new CngKeyCreationParameters()
|
||||
{
|
||||
ExportPolicy = CngExportPolicies.AllowPlaintextExport,
|
||||
};
|
||||
|
||||
CngProperty keySizeProperty = new CngProperty(NCryptNative.KeyPropertyName.Length,
|
||||
BitConverter.GetBytes(KeySize),
|
||||
CngPropertyOptions.None);
|
||||
@@ -154,7 +158,22 @@ namespace System.Security.Cryptography
|
||||
}
|
||||
|
||||
_key = value;
|
||||
KeySize = _key.KeySize;
|
||||
|
||||
// Our LegalKeySizes value stores the values that we encoded as being the correct
|
||||
// legal key size limitations for this algorithm, as documented on MSDN.
|
||||
//
|
||||
// But on a new OS version we might not question if our limit is accurate, or MSDN
|
||||
// could have been innacurate to start with.
|
||||
//
|
||||
// Since the key is already loaded, we know that Windows thought it to be valid;
|
||||
// therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance
|
||||
// check.
|
||||
//
|
||||
// For RSA there are known cases where this change matters. RSACryptoServiceProvider can
|
||||
// create a 384-bit RSA key, which we consider too small to be legal. It can also create
|
||||
// a 1032-bit RSA key, which we consider illegal because it doesn't match our 64-bit
|
||||
// alignment requirement. (In both cases Windows loads it just fine)
|
||||
KeySizeValue = _key.KeySize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,6 +563,25 @@ namespace System.Security.Cryptography
|
||||
throw new CryptographicException(SR.GetString(SR.Cryptography_UnsupportedPaddingMode));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The members
|
||||
* DecryptValue
|
||||
* EncryptValue
|
||||
* get_KeyExchangeAlgorithm
|
||||
* get_SignatureAlgorithm
|
||||
* are all implemented on RSA as of net46.
|
||||
*
|
||||
* But in servicing situations, System.Core.dll can get patched onto a machine which has mscorlib < net46, meaning
|
||||
* these abstract members have no implementation.
|
||||
*
|
||||
* To keep servicing simple, we'll redefine the overrides here. Since this type is sealed it only affects reflection,
|
||||
* as there are no derived types to mis-target base.-invocations.
|
||||
*/
|
||||
public override byte[] DecryptValue(byte[] rgb) { throw new NotSupportedException(SR.NotSupported_Method); }
|
||||
public override byte[] EncryptValue(byte[] rgb) { throw new NotSupportedException(SR.NotSupported_Method); }
|
||||
public override string KeyExchangeAlgorithm { get { return "RSA"; } }
|
||||
public override string SignatureAlgorithm { get { return "RSA"; } }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +71,14 @@ namespace System.Security.Cryptography.X509Certificates
|
||||
{
|
||||
if (privateKeyHandle == null)
|
||||
{
|
||||
if (LocalAppContextSwitches.DontReliablyClonePrivateKey)
|
||||
return (RSA)certificate.PrivateKey;
|
||||
|
||||
// fall back to CAPI if we cannot acquire the key using CNG.
|
||||
return (RSA)certificate.PrivateKey;
|
||||
RSACryptoServiceProvider rsaCsp = (RSACryptoServiceProvider)certificate.PrivateKey;
|
||||
CspParameters cspParameters = DSACertificateExtensions.CopyCspParameters(rsaCsp);
|
||||
RSACryptoServiceProvider clone = new RSACryptoServiceProvider(cspParameters);
|
||||
return clone;
|
||||
}
|
||||
|
||||
CngKey key = CngKey.Open(privateKeyHandle, CngKeyHandleOpenOptions.None);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user