You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection
|
||||
{
|
||||
public abstract class ChannelBinding : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
protected ChannelBinding()
|
||||
: base(true)
|
||||
{
|
||||
}
|
||||
|
||||
protected ChannelBinding(bool ownsHandle)
|
||||
: base(ownsHandle)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract int Size
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
namespace System.Security.Authentication.ExtendedProtection
|
||||
{
|
||||
// These should match the native SEC_ATTR_*_BINDINGS defines
|
||||
public enum ChannelBindingKind
|
||||
{
|
||||
Unknown = 0,
|
||||
Unique = 0x19,
|
||||
Endpoint = 0x1A
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection.Configuration
|
||||
{
|
||||
internal static class ExtendedProtectionConfigurationStrings
|
||||
{
|
||||
internal const string ExtendedProtectionPolicy = "extendedProtectionPolicy";
|
||||
internal const string PolicyEnforcement = "policyEnforcement";
|
||||
internal const string ProtectionScenario = "protectionScenario";
|
||||
internal const string CustomServiceNames = "customServiceNames";
|
||||
internal const string Name = "name";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection.Configuration
|
||||
{
|
||||
public sealed class ExtendedProtectionPolicyElement : ConfigurationElement
|
||||
{
|
||||
public ExtendedProtectionPolicyElement()
|
||||
{
|
||||
this.properties.Add(this.policyEnforcement);
|
||||
this.properties.Add(this.protectionScenario);
|
||||
this.properties.Add(this.customServiceNames);
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties
|
||||
{
|
||||
get { return this.properties; }
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ExtendedProtectionConfigurationStrings.PolicyEnforcement)]
|
||||
public PolicyEnforcement PolicyEnforcement {
|
||||
get {
|
||||
return (PolicyEnforcement)this[this.policyEnforcement];
|
||||
}
|
||||
set {
|
||||
this[this.policyEnforcement] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ExtendedProtectionConfigurationStrings.ProtectionScenario, DefaultValue=ProtectionScenario.TransportSelected)]
|
||||
public ProtectionScenario ProtectionScenario {
|
||||
get {
|
||||
return (ProtectionScenario)this[this.protectionScenario];
|
||||
}
|
||||
set {
|
||||
this[this.protectionScenario] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ExtendedProtectionConfigurationStrings.CustomServiceNames)]
|
||||
public ServiceNameElementCollection CustomServiceNames
|
||||
{
|
||||
get {
|
||||
return (ServiceNameElementCollection)this[this.customServiceNames];
|
||||
}
|
||||
}
|
||||
|
||||
public ExtendedProtectionPolicy BuildPolicy()
|
||||
{
|
||||
if (PolicyEnforcement == PolicyEnforcement.Never)
|
||||
{
|
||||
return new ExtendedProtectionPolicy(PolicyEnforcement.Never);
|
||||
}
|
||||
|
||||
ServiceNameCollection spns = null;
|
||||
|
||||
ServiceNameElementCollection spnCollection = CustomServiceNames;
|
||||
if (spnCollection != null && spnCollection.Count > 0)
|
||||
{
|
||||
List<string> spnList = new List<string>(spnCollection.Count);
|
||||
foreach (ServiceNameElement element in spnCollection)
|
||||
{
|
||||
spnList.Add(element.Name);
|
||||
}
|
||||
spns = new ServiceNameCollection(spnList);
|
||||
}
|
||||
|
||||
return new ExtendedProtectionPolicy(PolicyEnforcement, ProtectionScenario, spns);
|
||||
}
|
||||
|
||||
ConfigurationPropertyCollection properties = new ConfigurationPropertyCollection();
|
||||
|
||||
private static PolicyEnforcement DefaultPolicyEnforcement
|
||||
{
|
||||
get
|
||||
{
|
||||
return PolicyEnforcement.Never;
|
||||
}
|
||||
}
|
||||
|
||||
readonly ConfigurationProperty policyEnforcement =
|
||||
new ConfigurationProperty(ExtendedProtectionConfigurationStrings.PolicyEnforcement,
|
||||
typeof(PolicyEnforcement), DefaultPolicyEnforcement,
|
||||
ConfigurationPropertyOptions.None);
|
||||
|
||||
readonly ConfigurationProperty protectionScenario =
|
||||
new ConfigurationProperty(ExtendedProtectionConfigurationStrings.ProtectionScenario,
|
||||
typeof(ProtectionScenario), ProtectionScenario.TransportSelected,
|
||||
ConfigurationPropertyOptions.None);
|
||||
|
||||
readonly ConfigurationProperty customServiceNames =
|
||||
new ConfigurationProperty(ExtendedProtectionConfigurationStrings.CustomServiceNames,
|
||||
typeof(ServiceNameElementCollection), null,
|
||||
ConfigurationPropertyOptions.None);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Configuration;
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection.Configuration
|
||||
{
|
||||
public sealed class ServiceNameElement : ConfigurationElement
|
||||
{
|
||||
public ServiceNameElement()
|
||||
{
|
||||
this.properties.Add(this.name);
|
||||
}
|
||||
|
||||
[ConfigurationProperty(ExtendedProtectionConfigurationStrings.Name)]
|
||||
public string Name
|
||||
{
|
||||
get { return (string)this[this.name]; }
|
||||
set { this[this.name] = value; }
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.properties;
|
||||
}
|
||||
}
|
||||
|
||||
internal string Key
|
||||
{
|
||||
get { return this.Name; }
|
||||
}
|
||||
|
||||
ConfigurationPropertyCollection properties = new ConfigurationPropertyCollection();
|
||||
|
||||
readonly ConfigurationProperty name =
|
||||
new ConfigurationProperty(ExtendedProtectionConfigurationStrings.Name,
|
||||
typeof(string), null,
|
||||
ConfigurationPropertyOptions.IsRequired);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Configuration;
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection.Configuration
|
||||
{
|
||||
[ConfigurationCollection(typeof(ServiceNameElement))]
|
||||
public sealed class ServiceNameElementCollection : ConfigurationElementCollection
|
||||
{
|
||||
public ServiceNameElementCollection()
|
||||
{
|
||||
}
|
||||
|
||||
public ServiceNameElement this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ServiceNameElement)BaseGet(index);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (BaseGet(index) != null)
|
||||
{
|
||||
BaseRemoveAt(index);
|
||||
}
|
||||
BaseAdd(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
public new ServiceNameElement this[string name]
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ServiceNameElement)BaseGet(name);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (BaseGet(name) != null)
|
||||
{
|
||||
BaseRemove(name);
|
||||
}
|
||||
BaseAdd(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(ServiceNameElement element)
|
||||
{
|
||||
BaseAdd(element);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
BaseClear();
|
||||
}
|
||||
|
||||
protected override ConfigurationElement CreateNewElement()
|
||||
{
|
||||
return new ServiceNameElement();
|
||||
}
|
||||
|
||||
protected override Object GetElementKey(ConfigurationElement element)
|
||||
{
|
||||
if (element == null)
|
||||
throw new ArgumentNullException("element");
|
||||
return ((ServiceNameElement)element).Key;
|
||||
}
|
||||
|
||||
public int IndexOf(ServiceNameElement element)
|
||||
{
|
||||
return BaseIndexOf(element);
|
||||
}
|
||||
|
||||
public void Remove(ServiceNameElement element)
|
||||
{
|
||||
if (element == null)
|
||||
throw new ArgumentNullException("element");
|
||||
BaseRemove(element.Key);
|
||||
}
|
||||
|
||||
public void Remove(string name)
|
||||
{
|
||||
BaseRemove(name);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
BaseRemoveAt(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains the necessary settings for specifying how Extended Protection
|
||||
/// should behave. Use one of the Build* methods to create an instance of this type.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[TypeConverter(typeof(ExtendedProtectionPolicyTypeConverter))]
|
||||
public class ExtendedProtectionPolicy : ISerializable
|
||||
{
|
||||
private const string policyEnforcementName = "policyEnforcement";
|
||||
private const string protectionScenarioName = "protectionScenario";
|
||||
private const string customServiceNamesName = "customServiceNames";
|
||||
private const string customChannelBindingName = "customChannelBinding";
|
||||
|
||||
private ServiceNameCollection customServiceNames;
|
||||
private PolicyEnforcement policyEnforcement;
|
||||
private ProtectionScenario protectionScenario;
|
||||
private ChannelBinding customChannelBinding;
|
||||
|
||||
public ExtendedProtectionPolicy(PolicyEnforcement policyEnforcement,
|
||||
ProtectionScenario protectionScenario,
|
||||
ServiceNameCollection customServiceNames)
|
||||
{
|
||||
if (policyEnforcement == PolicyEnforcement.Never)
|
||||
{
|
||||
throw new ArgumentException(SR.GetString(SR.security_ExtendedProtectionPolicy_UseDifferentConstructorForNever), "policyEnforcement");
|
||||
}
|
||||
if (customServiceNames != null && customServiceNames.Count == 0)
|
||||
{
|
||||
throw new ArgumentException(SR.GetString(SR.security_ExtendedProtectionPolicy_NoEmptyServiceNameCollection), "customServiceNames");
|
||||
}
|
||||
|
||||
this.policyEnforcement = policyEnforcement;
|
||||
this.protectionScenario = protectionScenario;
|
||||
this.customServiceNames = customServiceNames;
|
||||
}
|
||||
|
||||
public ExtendedProtectionPolicy(PolicyEnforcement policyEnforcement,
|
||||
ProtectionScenario protectionScenario,
|
||||
ICollection customServiceNames)
|
||||
: this(policyEnforcement, protectionScenario,
|
||||
customServiceNames == null ? (ServiceNameCollection)null : new ServiceNameCollection(customServiceNames))
|
||||
{
|
||||
}
|
||||
|
||||
public ExtendedProtectionPolicy(PolicyEnforcement policyEnforcement,
|
||||
ChannelBinding customChannelBinding)
|
||||
{
|
||||
if (policyEnforcement == PolicyEnforcement.Never)
|
||||
{
|
||||
throw new ArgumentException(SR.GetString(SR.security_ExtendedProtectionPolicy_UseDifferentConstructorForNever), "policyEnforcement");
|
||||
}
|
||||
if (customChannelBinding == null)
|
||||
{
|
||||
throw new ArgumentNullException("customChannelBinding");
|
||||
}
|
||||
|
||||
this.policyEnforcement = policyEnforcement;
|
||||
this.protectionScenario = ProtectionScenario.TransportSelected;
|
||||
this.customChannelBinding = customChannelBinding;
|
||||
}
|
||||
|
||||
public ExtendedProtectionPolicy(PolicyEnforcement policyEnforcement)
|
||||
{
|
||||
// this is the only constructor which allows PolicyEnforcement.Never.
|
||||
this.policyEnforcement = policyEnforcement;
|
||||
this.protectionScenario = ProtectionScenario.TransportSelected;
|
||||
}
|
||||
|
||||
protected ExtendedProtectionPolicy(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
policyEnforcement = (PolicyEnforcement)info.GetInt32(policyEnforcementName);
|
||||
protectionScenario = (ProtectionScenario)info.GetInt32(protectionScenarioName);
|
||||
customServiceNames = (ServiceNameCollection)info.GetValue(customServiceNamesName, typeof(ServiceNameCollection));
|
||||
|
||||
byte[] channelBindingData = (byte[])info.GetValue(customChannelBindingName, typeof(byte[]));
|
||||
if (channelBindingData != null)
|
||||
{
|
||||
customChannelBinding = SafeLocalFreeChannelBinding.LocalAlloc(channelBindingData.Length);
|
||||
Marshal.Copy(channelBindingData, 0, customChannelBinding.DangerousGetHandle(), channelBindingData.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public ServiceNameCollection CustomServiceNames
|
||||
{
|
||||
get { return customServiceNames; }
|
||||
}
|
||||
|
||||
public PolicyEnforcement PolicyEnforcement
|
||||
{
|
||||
get { return policyEnforcement; }
|
||||
}
|
||||
|
||||
public ProtectionScenario ProtectionScenario
|
||||
{
|
||||
get { return protectionScenario; }
|
||||
}
|
||||
|
||||
public ChannelBinding CustomChannelBinding
|
||||
{
|
||||
get { return customChannelBinding; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("ProtectionScenario=");
|
||||
sb.Append(protectionScenario.ToString());
|
||||
sb.Append("; PolicyEnforcement=");
|
||||
sb.Append(policyEnforcement.ToString());
|
||||
|
||||
sb.Append("; CustomChannelBinding=");
|
||||
if (customChannelBinding == null)
|
||||
{
|
||||
sb.Append("<null>");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(customChannelBinding.ToString());
|
||||
}
|
||||
|
||||
sb.Append("; ServiceNames=");
|
||||
if (customServiceNames == null)
|
||||
{
|
||||
sb.Append("<null>");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool first = true;
|
||||
foreach (string serviceName in customServiceNames)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
|
||||
sb.Append(serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static bool OSSupportsExtendedProtection
|
||||
{
|
||||
get
|
||||
{
|
||||
return AuthenticationManager.OSSupportsExtendedProtection;
|
||||
}
|
||||
}
|
||||
|
||||
[SecurityPermissionAttribute(SecurityAction.LinkDemand, SerializationFormatter = true)]
|
||||
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue(policyEnforcementName, (int)policyEnforcement);
|
||||
info.AddValue(protectionScenarioName, (int)protectionScenario);
|
||||
info.AddValue(customServiceNamesName, customServiceNames, typeof(ServiceNameCollection));
|
||||
|
||||
if (customChannelBinding == null)
|
||||
{
|
||||
info.AddValue(customChannelBindingName, null, typeof(byte[]));
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] channelBindingData = new byte[customChannelBinding.Size];
|
||||
Marshal.Copy(customChannelBinding.DangerousGetHandle(), channelBindingData, 0, customChannelBinding.Size);
|
||||
info.AddValue(customChannelBindingName, channelBindingData, typeof(byte[]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design.Serialization;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection
|
||||
{
|
||||
public class ExtendedProtectionPolicyTypeConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(InstanceDescriptor))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.CanConvertTo(context, destinationType);
|
||||
}
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(InstanceDescriptor))
|
||||
{
|
||||
ExtendedProtectionPolicy policy = value as ExtendedProtectionPolicy;
|
||||
|
||||
if (policy != null)
|
||||
{
|
||||
Type[] parameterTypes;
|
||||
object[] parameterValues;
|
||||
|
||||
if (policy.PolicyEnforcement == PolicyEnforcement.Never)
|
||||
{
|
||||
parameterTypes = new Type[] { typeof(PolicyEnforcement) };
|
||||
parameterValues = new object[] { PolicyEnforcement.Never };
|
||||
}
|
||||
else
|
||||
{
|
||||
parameterTypes = new Type[] { typeof(PolicyEnforcement), typeof(ProtectionScenario), typeof(ICollection) };
|
||||
|
||||
object[] customServiceNames = null;
|
||||
if (policy.CustomServiceNames != null && policy.CustomServiceNames.Count > 0)
|
||||
{
|
||||
customServiceNames = new object[policy.CustomServiceNames.Count];
|
||||
((ICollection)policy.CustomServiceNames).CopyTo(customServiceNames, 0);
|
||||
}
|
||||
|
||||
parameterValues = new object[] { policy.PolicyEnforcement, policy.ProtectionScenario, customServiceNames };
|
||||
}
|
||||
|
||||
ConstructorInfo constructor = typeof(ExtendedProtectionPolicy).GetConstructor(parameterTypes);
|
||||
return new InstanceDescriptor(constructor, parameterValues);
|
||||
}
|
||||
}
|
||||
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection
|
||||
{
|
||||
public enum PolicyEnforcement
|
||||
{
|
||||
Never,
|
||||
WhenSupported,
|
||||
Always
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection
|
||||
{
|
||||
public enum ProtectionScenario
|
||||
{
|
||||
TransportSelected,
|
||||
TrustedProxy
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection
|
||||
{
|
||||
// derived from ReadOnlyCollectionBase because it needs to be back ported to .Net 1.x
|
||||
[SuppressMessage("Microsoft.Design","CA1058:TypesShouldNotExtendCertainBaseTypes", Justification="changing this would be a breaking change; this code has already shipped")]
|
||||
[Serializable]
|
||||
public class ServiceNameCollection : ReadOnlyCollectionBase
|
||||
{
|
||||
public ServiceNameCollection(ICollection items)
|
||||
{
|
||||
if (items == null) {
|
||||
throw new ArgumentNullException("items");
|
||||
}
|
||||
|
||||
// Normalize and filter for duplicates
|
||||
foreach (string serviceName in items)
|
||||
{
|
||||
AddIfNew(InnerList, serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
public ServiceNameCollection Merge(string serviceName)
|
||||
{
|
||||
ArrayList newServiceNames = new ArrayList(); // be compatible with .Net 1.x; no generics
|
||||
newServiceNames.AddRange(this.InnerList);
|
||||
|
||||
AddIfNew(newServiceNames, serviceName);
|
||||
|
||||
ServiceNameCollection newCollection = new ServiceNameCollection(newServiceNames);
|
||||
return newCollection;
|
||||
}
|
||||
|
||||
public ServiceNameCollection Merge(IEnumerable serviceNames)
|
||||
{
|
||||
ArrayList newServiceNames = new ArrayList(); // be compatible with .Net 1.x; no generics
|
||||
newServiceNames.AddRange(this.InnerList);
|
||||
|
||||
// we have a pretty bad performance here: O(n^2), but since service name lists should
|
||||
// be small (<<50) and Merge() should not be called frequently, this shouldn't be an issue
|
||||
foreach (object item in serviceNames) {
|
||||
AddIfNew(newServiceNames, item as string);
|
||||
}
|
||||
|
||||
ServiceNameCollection newCollection = new ServiceNameCollection(newServiceNames);
|
||||
return newCollection;
|
||||
}
|
||||
|
||||
// Normalize, check for duplicates, and add if the value is unique
|
||||
private static void AddIfNew(ArrayList newServiceNames, string serviceName)
|
||||
{
|
||||
if (String.IsNullOrEmpty(serviceName)) {
|
||||
throw new ArgumentException(SR.GetString(SR.security_ServiceNameCollection_EmptyServiceName));
|
||||
}
|
||||
|
||||
serviceName = NormalizeServiceName(serviceName);
|
||||
|
||||
if (!Contains(serviceName, newServiceNames)) {
|
||||
newServiceNames.Add(serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
// Assumes searchServiceName and serviceNames have already been normalized
|
||||
internal static bool Contains(string searchServiceName, ICollection serviceNames)
|
||||
{
|
||||
Debug.Assert(serviceNames != null);
|
||||
Debug.Assert(!String.IsNullOrEmpty(searchServiceName));
|
||||
|
||||
foreach (string serviceName in serviceNames) {
|
||||
if (Match(serviceName, searchServiceName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Contains(string searchServiceName)
|
||||
{
|
||||
string searchName = NormalizeServiceName(searchServiceName);
|
||||
|
||||
return Contains(searchName, InnerList);
|
||||
}
|
||||
|
||||
// Normalizes any punycode to unicode in an Service Name (SPN) host.
|
||||
// If the algorithm fails at any point then the original input is returned.
|
||||
// ServiceName is in one of the following forms:
|
||||
// prefix/host
|
||||
// prefix/host:port
|
||||
// prefix/host/DistinguishedName
|
||||
// prefix/host:port/DistinguishedName
|
||||
internal static string NormalizeServiceName(string inputServiceName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(inputServiceName))
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
// Separate out the prefix
|
||||
int shashIndex = inputServiceName.IndexOf('/');
|
||||
if (shashIndex < 0)
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
string prefix = inputServiceName.Substring(0, shashIndex + 1); // Includes slash
|
||||
string hostPortAndDistinguisher = inputServiceName.Substring(shashIndex + 1); // Excludes slash
|
||||
|
||||
if (string.IsNullOrWhiteSpace(hostPortAndDistinguisher))
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
string host = hostPortAndDistinguisher;
|
||||
string port = string.Empty;
|
||||
string distinguisher = string.Empty;
|
||||
|
||||
// Check for the absence of a port or distinguisher.
|
||||
UriHostNameType hostType = Uri.CheckHostName(hostPortAndDistinguisher);
|
||||
if (hostType == UriHostNameType.Unknown)
|
||||
{
|
||||
string hostAndPort = hostPortAndDistinguisher;
|
||||
|
||||
// Check for distinguisher
|
||||
int nextSlashIndex = hostPortAndDistinguisher.IndexOf('/');
|
||||
if (nextSlashIndex >= 0)
|
||||
{
|
||||
// host:port/distinguisher or host/distinguisher
|
||||
hostAndPort = hostPortAndDistinguisher.Substring(0, nextSlashIndex); // Excludes Slash
|
||||
distinguisher = hostPortAndDistinguisher.Substring(nextSlashIndex); // Includes Slash
|
||||
host = hostAndPort; // We don't know if there is a port yet.
|
||||
|
||||
// No need to validate the distinguisher
|
||||
}
|
||||
|
||||
// Check for port
|
||||
int colonIndex = hostAndPort.LastIndexOf(':'); // Allow IPv6 addresses
|
||||
if (colonIndex >= 0)
|
||||
{
|
||||
// host:port
|
||||
host = hostAndPort.Substring(0, colonIndex); // Excludes colon
|
||||
port = hostAndPort.Substring(colonIndex + 1); // Excludes colon
|
||||
|
||||
// Loosely validate the port just to make sure it was a port and not something else
|
||||
UInt16 portValue;
|
||||
if (!UInt16.TryParse(port, NumberStyles.Integer, CultureInfo.InvariantCulture, out portValue))
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
// Re-include the colon for the final output. Do not change the port format.
|
||||
port = hostAndPort.Substring(colonIndex);
|
||||
}
|
||||
|
||||
hostType = Uri.CheckHostName(host); // Revaidate the host
|
||||
}
|
||||
|
||||
if (hostType != UriHostNameType.Dns)
|
||||
{
|
||||
// UriHostNameType.IPv4, UriHostNameType.IPv6: Do not normalize IPv4/6 hosts.
|
||||
// UriHostNameType.Basic: This is never returned by CheckHostName today
|
||||
// UriHostNameType.Unknown: Nothing recognizable to normalize
|
||||
// default Some new UriHostNameType?
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
// Now we have a valid DNS host, normalize it.
|
||||
|
||||
Uri constructedUri;
|
||||
// This shouldn't fail, but we need to avoid any unexpected exceptions on this code path.
|
||||
if (!Uri.TryCreate(Uri.UriSchemeHttp + Uri.SchemeDelimiter + host, UriKind.Absolute, out constructedUri))
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
string normalizedHost = constructedUri.GetComponents(
|
||||
UriComponents.NormalizedHost, UriFormat.SafeUnescaped);
|
||||
|
||||
string normalizedServiceName = string.Format(CultureInfo.InvariantCulture,
|
||||
"{0}{1}{2}{3}", prefix, normalizedHost, port, distinguisher);
|
||||
|
||||
// Don't return the new one unless we absolutely have to. It may have only changed casing.
|
||||
if (Match(inputServiceName, normalizedServiceName))
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
return normalizedServiceName;
|
||||
}
|
||||
|
||||
// Assumes already normalized
|
||||
internal static bool Match(string serviceName1, string serviceName2)
|
||||
{
|
||||
return (String.Compare(serviceName1, serviceName2, StringComparison.OrdinalIgnoreCase) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="TokenBinding.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Security.Authentication.ExtendedProtection
|
||||
{
|
||||
|
||||
public enum TokenBindingType
|
||||
{
|
||||
Provided = 0,
|
||||
Referred = 1
|
||||
};
|
||||
|
||||
public class TokenBinding
|
||||
{
|
||||
internal TokenBinding(TokenBindingType bindingType, byte[] rawData)
|
||||
{
|
||||
BindingType = bindingType;
|
||||
_rawTokenBindingId = rawData;
|
||||
}
|
||||
|
||||
private byte[] _rawTokenBindingId = null;
|
||||
|
||||
public byte[] GetRawTokenBindingId()
|
||||
{
|
||||
return (_rawTokenBindingId != null) ? (byte[])_rawTokenBindingId.Clone() : null;
|
||||
}
|
||||
|
||||
public TokenBindingType BindingType
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace System.Security.Claims
|
||||
{
|
||||
public static class DynamicRoleClaimProvider
|
||||
{
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use ClaimsAuthenticationManager to add claims to a ClaimsIdentity", true)]
|
||||
public static void AddDynamicRoleClaims(ClaimsIdentity claimsIdentity, IEnumerable<Claim> claims)
|
||||
{
|
||||
claimsIdentity.ExternalClaims.Add(claims);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
//
|
||||
// AsnEncodedData.cs
|
||||
//
|
||||
|
||||
namespace System.Security.Cryptography {
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class AsnEncodedData {
|
||||
internal Oid m_oid = null;
|
||||
internal byte[] m_rawData = null;
|
||||
|
||||
internal AsnEncodedData (Oid oid) {
|
||||
m_oid = oid;
|
||||
}
|
||||
|
||||
internal AsnEncodedData (string oid, CAPI.CRYPTOAPI_BLOB encodedBlob) : this(oid, CAPI.BlobToByteArray(encodedBlob)) {}
|
||||
internal AsnEncodedData (Oid oid, CAPI.CRYPTOAPI_BLOB encodedBlob) : this(oid, CAPI.BlobToByteArray(encodedBlob)) {}
|
||||
|
||||
protected AsnEncodedData () {}
|
||||
|
||||
public AsnEncodedData (byte[] rawData) {
|
||||
Reset(null, rawData);
|
||||
}
|
||||
|
||||
public AsnEncodedData (string oid, byte[] rawData) {
|
||||
Reset(new Oid(oid), rawData);
|
||||
}
|
||||
|
||||
public AsnEncodedData (Oid oid, byte[] rawData) {
|
||||
Reset(oid, rawData);
|
||||
}
|
||||
|
||||
public AsnEncodedData (AsnEncodedData asnEncodedData) {
|
||||
if (asnEncodedData == null)
|
||||
throw new ArgumentNullException("asnEncodedData");
|
||||
Reset(asnEncodedData.m_oid, asnEncodedData.m_rawData);
|
||||
}
|
||||
|
||||
public Oid Oid {
|
||||
get {
|
||||
return m_oid;
|
||||
}
|
||||
set {
|
||||
if (value == null)
|
||||
m_oid = null;
|
||||
else
|
||||
m_oid = new Oid(value);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] RawData {
|
||||
get {
|
||||
return m_rawData;
|
||||
}
|
||||
set {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
m_rawData = (byte[]) value.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void CopyFrom (AsnEncodedData asnEncodedData) {
|
||||
if (asnEncodedData == null)
|
||||
throw new ArgumentNullException("asnEncodedData");
|
||||
Reset(asnEncodedData.m_oid, asnEncodedData.m_rawData);
|
||||
}
|
||||
|
||||
public virtual string Format (bool multiLine) {
|
||||
// Return empty string if no data to format.
|
||||
if (m_rawData == null || m_rawData.Length == 0)
|
||||
return String.Empty;
|
||||
|
||||
// If OID is not present, then we can force CryptFormatObject
|
||||
// to use hex formatting by providing an empty OID string.
|
||||
string oidValue = String.Empty;
|
||||
if (m_oid != null && m_oid.Value != null)
|
||||
oidValue = m_oid.Value;
|
||||
|
||||
return CAPI.CryptFormatObject(CAPI.X509_ASN_ENCODING,
|
||||
multiLine ? CAPI.CRYPT_FORMAT_STR_MULTI_LINE : 0,
|
||||
oidValue,
|
||||
m_rawData);
|
||||
}
|
||||
|
||||
private void Reset (Oid oid, byte[] rawData) {
|
||||
this.Oid = oid;
|
||||
this.RawData = rawData;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AsnEncodedDataCollection : ICollection {
|
||||
private ArrayList m_list = null;
|
||||
private Oid m_oid = null;
|
||||
|
||||
public AsnEncodedDataCollection () {
|
||||
m_list = new ArrayList();
|
||||
m_oid = null;
|
||||
}
|
||||
|
||||
public AsnEncodedDataCollection(AsnEncodedData asnEncodedData) : this() {
|
||||
m_list.Add(asnEncodedData);
|
||||
}
|
||||
|
||||
public int Add (AsnEncodedData asnEncodedData) {
|
||||
if (asnEncodedData == null)
|
||||
throw new ArgumentNullException("asnEncodedData");
|
||||
|
||||
//
|
||||
// If m_oid is not null, then OIDs must match.
|
||||
//
|
||||
if (m_oid != null) {
|
||||
string szOid1 = m_oid.Value;
|
||||
string szOid2 = asnEncodedData.Oid.Value;
|
||||
|
||||
if (szOid1 != null && szOid2 != null) {
|
||||
// Both are not null, so make sure OIDs match.
|
||||
if (String.Compare(szOid1, szOid2, StringComparison.OrdinalIgnoreCase) != 0)
|
||||
throw new CryptographicException(SR.GetString(SR.Cryptography_Asn_MismatchedOidInCollection));
|
||||
}
|
||||
else if (szOid1 != null || szOid2 != null) {
|
||||
// Can't be matching, since only one of them is null.
|
||||
throw new CryptographicException(SR.GetString(SR.Cryptography_Asn_MismatchedOidInCollection));
|
||||
}
|
||||
}
|
||||
|
||||
return m_list.Add(asnEncodedData);
|
||||
}
|
||||
|
||||
public void Remove (AsnEncodedData asnEncodedData) {
|
||||
if (asnEncodedData == null)
|
||||
throw new ArgumentNullException("asnEncodedData");
|
||||
m_list.Remove(asnEncodedData);
|
||||
}
|
||||
|
||||
public AsnEncodedData this[int index] {
|
||||
get {
|
||||
return (AsnEncodedData) m_list[index];
|
||||
}
|
||||
}
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
return m_list.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public AsnEncodedDataEnumerator GetEnumerator() {
|
||||
return new AsnEncodedDataEnumerator(this);
|
||||
}
|
||||
|
||||
/// <internalonly/>
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return new AsnEncodedDataEnumerator(this);
|
||||
}
|
||||
|
||||
/// <internalonly/>
|
||||
void ICollection.CopyTo(Array array, int index) {
|
||||
if (array == null)
|
||||
throw new ArgumentNullException("array");
|
||||
if (array.Rank != 1)
|
||||
throw new ArgumentException(SR.GetString(SR.Arg_RankMultiDimNotSupported));
|
||||
if (index < 0 || index >= array.Length)
|
||||
throw new ArgumentOutOfRangeException("index", SR.GetString(SR.ArgumentOutOfRange_Index));
|
||||
if (index + this.Count > array.Length)
|
||||
throw new ArgumentException(SR.GetString(SR.Argument_InvalidOffLen));
|
||||
|
||||
for (int i=0; i < this.Count; i++) {
|
||||
array.SetValue(this[i], index);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(AsnEncodedData[] array, int index) {
|
||||
((ICollection)this).CopyTo(array, index);
|
||||
}
|
||||
|
||||
public bool IsSynchronized {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Object SyncRoot {
|
||||
get {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AsnEncodedDataEnumerator : IEnumerator {
|
||||
private AsnEncodedDataCollection m_asnEncodedDatas;
|
||||
private int m_current;
|
||||
|
||||
private AsnEncodedDataEnumerator() {}
|
||||
internal AsnEncodedDataEnumerator(AsnEncodedDataCollection asnEncodedDatas) {
|
||||
m_asnEncodedDatas = asnEncodedDatas;
|
||||
m_current = -1;
|
||||
}
|
||||
|
||||
public AsnEncodedData Current {
|
||||
get {
|
||||
return m_asnEncodedDatas[m_current];
|
||||
}
|
||||
}
|
||||
|
||||
/// <internalonly/>
|
||||
Object IEnumerator.Current {
|
||||
get {
|
||||
return (Object) m_asnEncodedDatas[m_current];
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext() {
|
||||
if (m_current == ((int) m_asnEncodedDatas.Count - 1))
|
||||
return false;
|
||||
m_current++;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
m_current = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,495 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
//
|
||||
// BigInt.cs
|
||||
//
|
||||
// 11/06/2002
|
||||
//
|
||||
|
||||
namespace System.Security.Cryptography
|
||||
{
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
//
|
||||
// This is a pretty "crude" implementation of BigInt arithmetic operations.
|
||||
// This class is used in particular to convert certificate serial numbers from
|
||||
// hexadecimal representation to decimal format and vice versa.
|
||||
//
|
||||
// We are not very concerned about the perf characterestics of this implementation
|
||||
// for now. We perform all operations up to 128 bytes (which is enough for the current
|
||||
// purposes although this constant can be increased). Any overflow bytes are going to be lost.
|
||||
//
|
||||
// A BigInt is represented as a little endian byte array of size 128 bytes. All
|
||||
// arithmetic operations are performed in base 0x100 (256). The algorithms used
|
||||
// are simply the common primary school techniques for doing operations in base 10.
|
||||
//
|
||||
|
||||
internal sealed class BigInt {
|
||||
private byte[] m_elements;
|
||||
private const int m_maxbytes = 128; // 128 bytes is the maximum we can handle.
|
||||
// This means any overflow bits beyond 128 bytes
|
||||
// will be lost when doing arithmetic operations.
|
||||
private const int m_base = 0x100;
|
||||
private int m_size = 0;
|
||||
|
||||
internal BigInt () {
|
||||
m_elements = new byte[m_maxbytes];
|
||||
}
|
||||
|
||||
internal BigInt(byte b) {
|
||||
m_elements = new byte[m_maxbytes];
|
||||
SetDigit(0, b);
|
||||
}
|
||||
|
||||
//
|
||||
// Gets or sets the size of a BigInt.
|
||||
//
|
||||
|
||||
internal int Size {
|
||||
get {
|
||||
return m_size;
|
||||
}
|
||||
set {
|
||||
if (value > m_maxbytes)
|
||||
m_size = m_maxbytes;
|
||||
if (value < 0)
|
||||
m_size = 0;
|
||||
m_size = value;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Gets the digit at the specified index.
|
||||
//
|
||||
|
||||
internal byte GetDigit (int index) {
|
||||
if (index < 0 || index >= m_size)
|
||||
return 0;
|
||||
|
||||
return m_elements[index];
|
||||
}
|
||||
|
||||
//
|
||||
// Sets the digit at the specified index.
|
||||
//
|
||||
|
||||
internal void SetDigit (int index, byte digit) {
|
||||
if (index >= 0 && index < m_maxbytes) {
|
||||
m_elements[index] = digit;
|
||||
if (index >= m_size && digit != 0)
|
||||
m_size = (index + 1);
|
||||
if (index == m_size - 1 && digit == 0)
|
||||
m_size--;
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetDigit (int index, byte digit, ref int size) {
|
||||
if (index >= 0 && index < m_maxbytes) {
|
||||
m_elements[index] = digit;
|
||||
if (index >= size && digit != 0)
|
||||
size = (index + 1);
|
||||
if (index == size - 1 && digit == 0)
|
||||
size = (size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// overloaded operators.
|
||||
//
|
||||
|
||||
public static bool operator < (BigInt value1, BigInt value2) {
|
||||
if (value1 == null)
|
||||
return true;
|
||||
else if (value2 == null)
|
||||
return false;
|
||||
|
||||
int Len1 = value1.Size;
|
||||
int Len2 = value2.Size;
|
||||
|
||||
if (Len1 != Len2)
|
||||
return (Len1 < Len2);
|
||||
|
||||
while (Len1-- > 0) {
|
||||
if (value1.m_elements[Len1] != value2.m_elements[Len1])
|
||||
return (value1.m_elements[Len1] < value2.m_elements[Len1]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool operator > (BigInt value1, BigInt value2) {
|
||||
if (value1 == null)
|
||||
return false;
|
||||
else if (value2 == null)
|
||||
return true;
|
||||
|
||||
int Len1 = value1.Size;
|
||||
int Len2 = value2.Size;
|
||||
|
||||
if (Len1 != Len2)
|
||||
return (Len1 > Len2);
|
||||
|
||||
while (Len1-- > 0) {
|
||||
if (value1.m_elements[Len1] != value2.m_elements[Len1])
|
||||
return (value1.m_elements[Len1] > value2.m_elements[Len1]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool operator == (BigInt value1, BigInt value2) {
|
||||
if ((Object) value1 == null)
|
||||
return ((Object) value2 == null);
|
||||
else if ((Object) value2 == null)
|
||||
return ((Object) value1 == null);
|
||||
|
||||
int Len1 = value1.Size;
|
||||
int Len2 = value2.Size;
|
||||
|
||||
if (Len1 != Len2)
|
||||
return false;
|
||||
|
||||
for (int index = 0; index < Len1; index++) {
|
||||
if (value1.m_elements[index] != value2.m_elements[index])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator != (BigInt value1, BigInt value2) {
|
||||
return !(value1 == value2);
|
||||
}
|
||||
|
||||
public override bool Equals (Object obj) {
|
||||
if (obj is BigInt) {
|
||||
return (this == (BigInt) obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode () {
|
||||
int hash = 0;
|
||||
for (int index = 0; index < m_size; index++) {
|
||||
hash += GetDigit(index);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
//
|
||||
// Adds a and b and outputs the result in c.
|
||||
//
|
||||
|
||||
internal static void Add (BigInt a, byte b, ref BigInt c) {
|
||||
byte carry = b;
|
||||
int sum = 0;
|
||||
|
||||
int size = a.Size;
|
||||
int newSize = 0;
|
||||
for (int index = 0; index < size; index++) {
|
||||
sum = a.GetDigit(index) + carry;
|
||||
c.SetDigit(index, (byte) (sum & 0xFF), ref newSize);
|
||||
carry = (byte) ((sum >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
if (carry != 0)
|
||||
c.SetDigit(a.Size, carry, ref newSize);
|
||||
|
||||
c.Size = newSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Negates a BigInt value. Each byte is complemented, then we add 1 to it.
|
||||
//
|
||||
|
||||
internal static void Negate (ref BigInt a) {
|
||||
int newSize = 0;
|
||||
for (int index = 0; index < m_maxbytes; index++) {
|
||||
a.SetDigit(index, (byte) (~a.GetDigit(index) & 0xFF), ref newSize);
|
||||
}
|
||||
for (int index = 0; index < m_maxbytes; index++) {
|
||||
a.SetDigit(index, (byte) (a.GetDigit(index) + 1), ref newSize);
|
||||
if ((a.GetDigit(index) & 0xFF) != 0) break;
|
||||
a.SetDigit(index, (byte) (a.GetDigit(index) & 0xFF), ref newSize);
|
||||
}
|
||||
a.Size = newSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Subtracts b from a and outputs the result in c.
|
||||
//
|
||||
|
||||
internal static void Subtract (BigInt a, BigInt b, ref BigInt c) {
|
||||
byte borrow = 0;
|
||||
int diff = 0;
|
||||
|
||||
if (a < b) {
|
||||
Subtract(b, a, ref c);
|
||||
Negate(ref c);
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
int size = a.Size;
|
||||
int newSize = 0;
|
||||
for (index = 0; index < size; index++) {
|
||||
diff = a.GetDigit(index) - b.GetDigit(index) - borrow;
|
||||
borrow = 0;
|
||||
if (diff < 0) {
|
||||
diff += m_base;
|
||||
borrow = 1;
|
||||
}
|
||||
c.SetDigit(index, (byte) (diff & 0xFF), ref newSize);
|
||||
}
|
||||
|
||||
c.Size = newSize;
|
||||
}
|
||||
|
||||
//
|
||||
// multiplies a BigInt by an integer.
|
||||
//
|
||||
|
||||
private void Multiply (int b) {
|
||||
if (b == 0) {
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
int carry = 0, product = 0;
|
||||
int size = this.Size;
|
||||
int newSize = 0;
|
||||
for (int index = 0; index < size; index++) {
|
||||
product = b * GetDigit(index) + carry;
|
||||
carry = product / m_base;
|
||||
SetDigit(index, (byte) (product % m_base), ref newSize);
|
||||
}
|
||||
|
||||
if (carry != 0) {
|
||||
byte[] bytes = BitConverter.GetBytes(carry);
|
||||
for (int index = 0; index < bytes.Length; index++) {
|
||||
SetDigit(size + index, bytes[index], ref newSize);
|
||||
}
|
||||
}
|
||||
|
||||
this.Size = newSize;
|
||||
}
|
||||
|
||||
private static void Multiply (BigInt a, int b, ref BigInt c) {
|
||||
if (b == 0) {
|
||||
c.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
int carry = 0, product = 0;
|
||||
int size = a.Size;
|
||||
int newSize = 0;
|
||||
for (int index = 0; index < size; index++) {
|
||||
product = b * a.GetDigit(index) + carry;
|
||||
carry = product / m_base;
|
||||
c.SetDigit(index, (byte) (product % m_base), ref newSize);
|
||||
}
|
||||
|
||||
if (carry != 0) {
|
||||
byte[] bytes = BitConverter.GetBytes(carry);
|
||||
for (int index = 0; index < bytes.Length; index++) {
|
||||
c.SetDigit(size + index, bytes[index], ref newSize);
|
||||
}
|
||||
}
|
||||
|
||||
c.Size = newSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Divides a BigInt by a single byte.
|
||||
//
|
||||
|
||||
private void Divide (int b) {
|
||||
int carry = 0, quotient = 0;
|
||||
int bLen = this.Size;
|
||||
|
||||
int newSize = 0;
|
||||
while (bLen-- > 0) {
|
||||
quotient = m_base * carry + GetDigit(bLen);
|
||||
carry = quotient % b;
|
||||
SetDigit(bLen, (byte) (quotient / b), ref newSize);
|
||||
}
|
||||
|
||||
this.Size = newSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Integer division of one BigInt by another.
|
||||
//
|
||||
|
||||
internal static void Divide (BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder) {
|
||||
// Avoid extra computations in special cases.
|
||||
|
||||
if (numerator < denominator) {
|
||||
quotient.Clear();
|
||||
remainder.CopyFrom(numerator);
|
||||
return;
|
||||
}
|
||||
|
||||
if (numerator == denominator) {
|
||||
quotient.Clear(); quotient.SetDigit(0, 1);
|
||||
remainder.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
BigInt dividend = new BigInt();
|
||||
dividend.CopyFrom(numerator);
|
||||
BigInt divisor = new BigInt();
|
||||
divisor.CopyFrom(denominator);
|
||||
|
||||
uint zeroCount = 0;
|
||||
// We pad the divisor with zeros until its size equals that of the dividend.
|
||||
while (divisor.Size < dividend.Size) {
|
||||
divisor.Multiply(m_base);
|
||||
zeroCount++;
|
||||
}
|
||||
|
||||
if (divisor > dividend) {
|
||||
divisor.Divide(m_base);
|
||||
zeroCount--;
|
||||
}
|
||||
|
||||
// Use school division techniques, make a guess for how many times
|
||||
// divisor goes into dividend, making adjustment if necessary.
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
int c = 0;
|
||||
|
||||
BigInt hold = new BigInt();
|
||||
quotient.Clear();
|
||||
for (int index = 0; index <= zeroCount; index++) {
|
||||
a = dividend.Size == divisor.Size ? dividend.GetDigit(dividend.Size - 1) :
|
||||
m_base * dividend.GetDigit(dividend.Size - 1) + dividend.GetDigit(dividend.Size - 2);
|
||||
b = divisor.GetDigit(divisor.Size - 1);
|
||||
c = a / b;
|
||||
|
||||
if (c >= m_base)
|
||||
c = 0xFF;
|
||||
|
||||
Multiply(divisor, c, ref hold);
|
||||
while (hold > dividend) {
|
||||
c--;
|
||||
Multiply(divisor, c, ref hold);
|
||||
}
|
||||
|
||||
quotient.Multiply(m_base);
|
||||
Add(quotient, (byte) c, ref quotient);
|
||||
Subtract(dividend, hold, ref dividend);
|
||||
divisor.Divide(m_base);
|
||||
}
|
||||
remainder.CopyFrom(dividend);
|
||||
}
|
||||
|
||||
//
|
||||
// copies a BigInt value.
|
||||
//
|
||||
|
||||
internal void CopyFrom (BigInt a) {
|
||||
Array.Copy(a.m_elements, m_elements, m_maxbytes);
|
||||
m_size = a.m_size;
|
||||
}
|
||||
|
||||
//
|
||||
// This method returns true if the BigInt is equal to 0, false otherwise.
|
||||
//
|
||||
|
||||
internal bool IsZero () {
|
||||
for (int index = 0; index < m_size; index++) {
|
||||
if (m_elements[index] != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// returns the array in machine format, i.e. little endian format (as an integer).
|
||||
//
|
||||
|
||||
internal byte[] ToByteArray() {
|
||||
byte[] result = new byte[this.Size];
|
||||
Array.Copy(m_elements, result, this.Size);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// zeroizes the content of the internal array.
|
||||
//
|
||||
|
||||
internal void Clear () {
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Imports a hexadecimal string into a BigInt bit representation.
|
||||
//
|
||||
|
||||
internal void FromHexadecimal (string hexNum) {
|
||||
byte[] hex = X509Utils.DecodeHexString(hexNum);
|
||||
Array.Reverse(hex);
|
||||
int size = X509Utils.GetHexArraySize(hex);
|
||||
Array.Copy(hex, m_elements, size);
|
||||
this.Size = size;
|
||||
}
|
||||
|
||||
//
|
||||
// Imports a decimal string into a BigInt bit representation.
|
||||
//
|
||||
|
||||
internal void FromDecimal (string decNum) {
|
||||
BigInt c = new BigInt();
|
||||
BigInt tmp = new BigInt();
|
||||
int length = decNum.Length;
|
||||
for (int index = 0; index < length; index++) {
|
||||
// just ignore invalid characters. No need to raise an exception.
|
||||
if (decNum[index] > '9' || decNum[index] < '0')
|
||||
continue;
|
||||
Multiply(c, 10, ref tmp);
|
||||
Add(tmp, (byte) (decNum[index] - '0'), ref c);
|
||||
}
|
||||
CopyFrom(c);
|
||||
}
|
||||
|
||||
//
|
||||
// Exports the BigInt representation as a decimal string.
|
||||
//
|
||||
|
||||
private static readonly char[] decValues = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||
internal string ToDecimal ()
|
||||
{
|
||||
if (IsZero())
|
||||
return "0";
|
||||
|
||||
BigInt ten = new BigInt(0xA);
|
||||
BigInt numerator = new BigInt();
|
||||
BigInt quotient = new BigInt();
|
||||
BigInt remainder = new BigInt();
|
||||
|
||||
numerator.CopyFrom(this);
|
||||
|
||||
// Each hex digit can account for log(16) = 1.21 decimal digits. Times two hex digits in a byte
|
||||
// and m_size bytes used in this BigInt, yields the maximum number of characters for the decimal
|
||||
// representation of the BigInt.
|
||||
char[] dec = new char[(int)Math.Ceiling(m_size * 2 * 1.21)];
|
||||
|
||||
int index = 0;
|
||||
do
|
||||
{
|
||||
Divide(numerator, ten, ref quotient, ref remainder);
|
||||
dec[index++] = decValues[remainder.IsZero() ? 0 : (int)remainder.m_elements[0]];
|
||||
numerator.CopyFrom(quotient);
|
||||
} while (quotient.IsZero() == false);
|
||||
|
||||
Array.Reverse(dec, 0, index);
|
||||
return new String(dec, 0, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
45e47aac1d7e4106cadcd0c6927908a3732846f3
|
||||
@@ -0,0 +1,249 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
//
|
||||
// Oid.cs
|
||||
//
|
||||
|
||||
namespace System.Security.Cryptography {
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
// Values taken from wincrypt.h
|
||||
public enum OidGroup {
|
||||
All = 0,
|
||||
HashAlgorithm = 1,
|
||||
EncryptionAlgorithm = 2,
|
||||
PublicKeyAlgorithm = 3,
|
||||
SignatureAlgorithm = 4,
|
||||
Attribute = 5,
|
||||
ExtensionOrAttribute = 6,
|
||||
EnhancedKeyUsage = 7,
|
||||
Policy = 8,
|
||||
Template = 9,
|
||||
KeyDerivationFunction = 10
|
||||
}
|
||||
|
||||
public sealed class Oid {
|
||||
private string m_value = null;
|
||||
private string m_friendlyName = null;
|
||||
private OidGroup m_group = OidGroup.All;
|
||||
|
||||
public Oid() { }
|
||||
|
||||
public Oid(string oid) : this(oid, OidGroup.All, true)
|
||||
{
|
||||
}
|
||||
|
||||
internal Oid(string oid, OidGroup group, bool lookupFriendlyName)
|
||||
{
|
||||
if (lookupFriendlyName)
|
||||
{
|
||||
// If we were passed the friendly name, retrieve the value string.
|
||||
string oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, oid, group);
|
||||
if (oidValue == null)
|
||||
oidValue = oid;
|
||||
this.Value = oidValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Value = oid;
|
||||
}
|
||||
|
||||
m_group = group;
|
||||
}
|
||||
|
||||
public Oid(string value, string friendlyName) {
|
||||
m_value = value;
|
||||
m_friendlyName = friendlyName;
|
||||
}
|
||||
|
||||
public Oid(Oid oid) {
|
||||
if (oid == null)
|
||||
throw new ArgumentNullException("oid");
|
||||
m_value = oid.m_value;
|
||||
m_friendlyName = oid.m_friendlyName;
|
||||
m_group = oid.m_group;
|
||||
}
|
||||
|
||||
private Oid(string value, string friendlyName, OidGroup group) {
|
||||
Debug.Assert(value != null);
|
||||
Debug.Assert(friendlyName != null);
|
||||
|
||||
m_value = value;
|
||||
m_friendlyName = friendlyName;
|
||||
m_group = group;
|
||||
}
|
||||
|
||||
public static Oid FromFriendlyName(string friendlyName, OidGroup group) {
|
||||
if (friendlyName == null) {
|
||||
throw new ArgumentNullException("friendlyName");
|
||||
}
|
||||
|
||||
string oidValue = X509Utils.FindOidInfo(CAPI.CRYPT_OID_INFO_NAME_KEY, friendlyName, group);
|
||||
if (oidValue == null) {
|
||||
throw new CryptographicException(SR.GetString(SR.Cryptography_Oid_InvalidValue));
|
||||
}
|
||||
|
||||
return new Oid(oidValue, friendlyName, group);
|
||||
}
|
||||
|
||||
public static Oid FromOidValue(string oidValue, OidGroup group) {
|
||||
if (oidValue == null) {
|
||||
throw new ArgumentNullException("oidValue");
|
||||
}
|
||||
|
||||
string friendlyName = X509Utils.FindOidInfo(CAPI.CRYPT_OID_INFO_OID_KEY, oidValue, group);
|
||||
if (friendlyName == null) {
|
||||
throw new CryptographicException(SR.GetString(SR.Cryptography_Oid_InvalidValue));
|
||||
}
|
||||
|
||||
return new Oid(oidValue, friendlyName, group);
|
||||
}
|
||||
|
||||
public string Value {
|
||||
get { return m_value; }
|
||||
set { m_value = value; }
|
||||
}
|
||||
|
||||
public string FriendlyName {
|
||||
get {
|
||||
if(m_friendlyName == null && m_value != null)
|
||||
m_friendlyName = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_OID_KEY, m_value, m_group);
|
||||
|
||||
return m_friendlyName;
|
||||
}
|
||||
set {
|
||||
m_friendlyName = value;
|
||||
// If we can find the matching OID value, then update it as well
|
||||
if (m_friendlyName != null) {
|
||||
// If FindOidInfo fails, we return a null string
|
||||
string oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, m_friendlyName, m_group);
|
||||
if (oidValue != null)
|
||||
m_value = oidValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class OidCollection : ICollection {
|
||||
private ArrayList m_list;
|
||||
|
||||
public OidCollection() {
|
||||
m_list = new ArrayList();
|
||||
}
|
||||
|
||||
public int Add(Oid oid) {
|
||||
return m_list.Add(oid);
|
||||
}
|
||||
|
||||
public Oid this[int index] {
|
||||
get {
|
||||
return m_list[index] as Oid;
|
||||
}
|
||||
}
|
||||
|
||||
// Indexer using an OID friendly name or value.
|
||||
public Oid this[string oid] {
|
||||
get {
|
||||
// If we were passed the friendly name, retrieve the value string.
|
||||
string oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, oid, OidGroup.All);
|
||||
if (oidValue == null)
|
||||
oidValue = oid;
|
||||
foreach (Oid entry in m_list) {
|
||||
if (entry.Value == oidValue)
|
||||
return entry;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
return m_list.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public OidEnumerator GetEnumerator() {
|
||||
return new OidEnumerator(this);
|
||||
}
|
||||
|
||||
/// <internalonly/>
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return new OidEnumerator(this);
|
||||
}
|
||||
|
||||
/// <internalonly/>
|
||||
void ICollection.CopyTo(Array array, int index) {
|
||||
if (array == null)
|
||||
throw new ArgumentNullException("array");
|
||||
if (array.Rank != 1)
|
||||
throw new ArgumentException(SR.GetString(SR.Arg_RankMultiDimNotSupported));
|
||||
if (index < 0 || index >= array.Length)
|
||||
throw new ArgumentOutOfRangeException("index", SR.GetString(SR.ArgumentOutOfRange_Index));
|
||||
if (index + this.Count > array.Length)
|
||||
throw new ArgumentException(SR.GetString(SR.Argument_InvalidOffLen));
|
||||
|
||||
for (int i=0; i < this.Count; i++) {
|
||||
array.SetValue(this[i], index);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(Oid[] array, int index) {
|
||||
((ICollection)this).CopyTo(array, index);
|
||||
}
|
||||
|
||||
public bool IsSynchronized {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Object SyncRoot {
|
||||
get {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class OidEnumerator : IEnumerator {
|
||||
private OidCollection m_oids;
|
||||
private int m_current;
|
||||
|
||||
private OidEnumerator() {}
|
||||
internal OidEnumerator(OidCollection oids) {
|
||||
m_oids = oids;
|
||||
m_current = -1;
|
||||
}
|
||||
|
||||
public Oid Current {
|
||||
get {
|
||||
return m_oids[m_current];
|
||||
}
|
||||
}
|
||||
|
||||
/// <internalonly/>
|
||||
Object IEnumerator.Current {
|
||||
get {
|
||||
return (Object) m_oids[m_current];
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext() {
|
||||
if (m_current == ((int) m_oids.Count - 1))
|
||||
return false;
|
||||
m_current++;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
m_current = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
|
||||
//
|
||||
// X500Name.cs
|
||||
//
|
||||
// 07/10/2003
|
||||
//
|
||||
|
||||
namespace System.Security.Cryptography.X509Certificates {
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
[Flags]
|
||||
public enum X500DistinguishedNameFlags {
|
||||
None = 0x0000,
|
||||
Reversed = 0x0001,
|
||||
|
||||
UseSemicolons = 0x0010,
|
||||
DoNotUsePlusSign = 0x0020,
|
||||
DoNotUseQuotes = 0x0040,
|
||||
UseCommas = 0x0080,
|
||||
UseNewLines = 0x0100,
|
||||
|
||||
UseUTF8Encoding = 0x1000,
|
||||
UseT61Encoding = 0x2000,
|
||||
ForceUTF8Encoding = 0x4000,
|
||||
}
|
||||
|
||||
public sealed class X500DistinguishedName : AsnEncodedData {
|
||||
private string m_distinguishedName = null;
|
||||
|
||||
//
|
||||
// Constructors.
|
||||
//
|
||||
|
||||
internal X500DistinguishedName (CAPI.CRYPTOAPI_BLOB encodedDistinguishedNameBlob) : base (new Oid(), encodedDistinguishedNameBlob) {}
|
||||
|
||||
public X500DistinguishedName (byte[] encodedDistinguishedName) : base(new Oid(), encodedDistinguishedName) {}
|
||||
|
||||
public X500DistinguishedName (AsnEncodedData encodedDistinguishedName) : base(encodedDistinguishedName) {}
|
||||
|
||||
public X500DistinguishedName (X500DistinguishedName distinguishedName) : base((AsnEncodedData) distinguishedName) {
|
||||
m_distinguishedName = distinguishedName.Name;
|
||||
}
|
||||
|
||||
public X500DistinguishedName (string distinguishedName) : this(distinguishedName, X500DistinguishedNameFlags.Reversed) {}
|
||||
|
||||
public X500DistinguishedName (string distinguishedName, X500DistinguishedNameFlags flag) : base(new Oid(), Encode(distinguishedName, flag)) {
|
||||
m_distinguishedName = distinguishedName;
|
||||
}
|
||||
|
||||
//
|
||||
// Public properties.
|
||||
//
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
if (m_distinguishedName == null)
|
||||
m_distinguishedName = Decode(X500DistinguishedNameFlags.Reversed);
|
||||
return m_distinguishedName;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Public methods.
|
||||
//
|
||||
|
||||
#if FEATURE_CORESYSTEM
|
||||
[SecuritySafeCritical]
|
||||
#endif
|
||||
public string Decode (X500DistinguishedNameFlags flag) {
|
||||
uint dwStrType = CAPI.CERT_X500_NAME_STR | MapNameToStrFlag(flag);
|
||||
unsafe {
|
||||
byte[] encodedDistinguishedName = this.m_rawData;
|
||||
fixed (byte * pbEncoded = encodedDistinguishedName) {
|
||||
CAPI.CRYPTOAPI_BLOB nameBlob;
|
||||
IntPtr pNameBlob = new IntPtr(&nameBlob);
|
||||
nameBlob.cbData = (uint) encodedDistinguishedName.Length;
|
||||
nameBlob.pbData = new IntPtr(pbEncoded);
|
||||
|
||||
uint cchDecoded = CAPI.CertNameToStrW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
|
||||
pNameBlob,
|
||||
dwStrType,
|
||||
SafeLocalAllocHandle.InvalidHandle,
|
||||
0);
|
||||
if (cchDecoded == 0)
|
||||
throw new CryptographicException(CAPI.CERT_E_INVALID_NAME);
|
||||
|
||||
using (SafeLocalAllocHandle pwszDecodeName = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(2 * cchDecoded))) {
|
||||
if (CAPI.CertNameToStrW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
|
||||
pNameBlob,
|
||||
dwStrType,
|
||||
pwszDecodeName,
|
||||
cchDecoded) == 0)
|
||||
throw new CryptographicException(CAPI.CERT_E_INVALID_NAME);
|
||||
return Marshal.PtrToStringUni(pwszDecodeName.DangerousGetHandle());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if FEATURE_CORESYSTEM
|
||||
[SecuritySafeCritical]
|
||||
#endif
|
||||
public override string Format (bool multiLine) {
|
||||
//
|
||||
// We must override to use the "numeric" pointer version of
|
||||
// CryptFormatObject, since X509 DN does not have an official OID.
|
||||
//
|
||||
|
||||
// Return empty string if no data to format.
|
||||
if (m_rawData == null || m_rawData.Length == 0)
|
||||
return String.Empty;
|
||||
|
||||
return CAPI.CryptFormatObject(CAPI.X509_ASN_ENCODING,
|
||||
multiLine ? CAPI.CRYPT_FORMAT_STR_MULTI_LINE : 0,
|
||||
new IntPtr(CAPI.X509_NAME),
|
||||
m_rawData);
|
||||
}
|
||||
|
||||
//
|
||||
// Private methods.
|
||||
//
|
||||
|
||||
#if FEATURE_CORESYSTEM
|
||||
[SecuritySafeCritical]
|
||||
#endif
|
||||
private unsafe static byte[] Encode (string distinguishedName, X500DistinguishedNameFlags flag) {
|
||||
if (distinguishedName == null)
|
||||
throw new ArgumentNullException("distinguishedName");
|
||||
|
||||
uint cbEncoded = 0;
|
||||
uint dwStrType = CAPI.CERT_X500_NAME_STR | MapNameToStrFlag(flag);
|
||||
|
||||
if (!CAPI.CertStrToNameW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
|
||||
distinguishedName,
|
||||
dwStrType,
|
||||
IntPtr.Zero,
|
||||
IntPtr.Zero,
|
||||
ref cbEncoded,
|
||||
IntPtr.Zero))
|
||||
throw new CryptographicException(Marshal.GetLastWin32Error());
|
||||
|
||||
byte[] encodedName = new byte[cbEncoded];
|
||||
fixed (byte * pbEncoded = encodedName) {
|
||||
if (!CAPI.CertStrToNameW(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
|
||||
distinguishedName,
|
||||
dwStrType,
|
||||
IntPtr.Zero,
|
||||
new IntPtr(pbEncoded),
|
||||
ref cbEncoded,
|
||||
IntPtr.Zero))
|
||||
throw new CryptographicException(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
return encodedName;
|
||||
}
|
||||
|
||||
private static uint MapNameToStrFlag (X500DistinguishedNameFlags flag) {
|
||||
// All values or'ed together. Change this if you add values to the enumeration.
|
||||
uint allFlags = 0x71F1;
|
||||
uint dwFlags = (uint) flag;
|
||||
if ((dwFlags & ~allFlags) != 0)
|
||||
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Arg_EnumIllegalVal), "flag"));
|
||||
|
||||
uint dwStrType = 0;
|
||||
if (dwFlags != 0) {
|
||||
if ((flag & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed)
|
||||
dwStrType |= CAPI.CERT_NAME_STR_REVERSE_FLAG;
|
||||
|
||||
if ((flag & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons)
|
||||
dwStrType |= CAPI.CERT_NAME_STR_SEMICOLON_FLAG;
|
||||
else if ((flag & X500DistinguishedNameFlags.UseCommas) == X500DistinguishedNameFlags.UseCommas)
|
||||
dwStrType |= CAPI.CERT_NAME_STR_COMMA_FLAG;
|
||||
else if ((flag & X500DistinguishedNameFlags.UseNewLines) == X500DistinguishedNameFlags.UseNewLines)
|
||||
dwStrType |= CAPI.CERT_NAME_STR_CRLF_FLAG;
|
||||
|
||||
if ((flag & X500DistinguishedNameFlags.DoNotUsePlusSign) == X500DistinguishedNameFlags.DoNotUsePlusSign)
|
||||
dwStrType |= CAPI.CERT_NAME_STR_NO_PLUS_FLAG;
|
||||
if ((flag & X500DistinguishedNameFlags.DoNotUseQuotes) == X500DistinguishedNameFlags.DoNotUseQuotes)
|
||||
dwStrType |= CAPI.CERT_NAME_STR_NO_QUOTING_FLAG;
|
||||
|
||||
if ((flag & X500DistinguishedNameFlags.ForceUTF8Encoding) == X500DistinguishedNameFlags.ForceUTF8Encoding)
|
||||
dwStrType |= CAPI.CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG;
|
||||
|
||||
if ((flag & X500DistinguishedNameFlags.UseUTF8Encoding) == X500DistinguishedNameFlags.UseUTF8Encoding)
|
||||
dwStrType |= CAPI.CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG;
|
||||
else if ((flag & X500DistinguishedNameFlags.UseT61Encoding) == X500DistinguishedNameFlags.UseT61Encoding)
|
||||
dwStrType |= CAPI.CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
|
||||
}
|
||||
return dwStrType;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user