Imported Upstream version 4.8.0.309

Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-11-10 13:04:39 +00:00
parent ee1447783b
commit 94b2861243
4912 changed files with 390737 additions and 49310 deletions

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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)
{

View File

@@ -1 +1 @@
2090063250746eae0b7a6eaec193aac86984b785
ff9b74d7295d3a52cf91057ee647d184edec0c5e

View File

@@ -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
}
}
}

View File

@@ -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));

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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,

View File

@@ -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));
}
}
}

View File

@@ -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>

View File

@@ -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));
}
}
}

View File

@@ -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
}
}

View File

@@ -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;
}
}

View File

@@ -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
}
}

View File

@@ -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