Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,187 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel
{
using System.Collections.Generic;
using System.Text;
static class Asn1IntegerConverter
{
static List<byte[]> powersOfTwo = new List<byte[]>(new byte[][] { new byte[] { 1 } });
readonly static char[] digitMap = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
public static string Asn1IntegerToDecimalString(byte[] asn1)
{
if (asn1 == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("asn1");
if (asn1.Length == 0)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("asn1", SR.GetString(SR.LengthOfArrayToConvertMustGreaterThanZero)));
List<byte> positiveDecimalDigits = new List<byte>((asn1.Length * 8) / 3);
int absoluteBitNumber = 0;
byte currentByte;
// Since X509Certificate.GetSerialNumber return the little-endian,
// the most significant is at the last byte.
for (int byteNumber = 0; byteNumber < asn1.Length - 1; byteNumber++)
{
currentByte = asn1[byteNumber];
for (int i = 0; i < 8; i++)
{
if ((currentByte & 1) == 1)
{
AddSecondDecimalToFirst(positiveDecimalDigits, TwoToThePowerOf(absoluteBitNumber));
}
absoluteBitNumber++;
currentByte >>= 1;
}
}
// Special case the most significant bit of the most significant byte as a negative value
currentByte = asn1[asn1.Length - 1];
for (int i = 0; i < 7; i++)
{
if ((currentByte & 1) == 1)
{
AddSecondDecimalToFirst(positiveDecimalDigits, TwoToThePowerOf(absoluteBitNumber));
}
absoluteBitNumber++;
currentByte >>= 1;
}
StringBuilder result = new StringBuilder(positiveDecimalDigits.Count + 1);
List<byte> resultDigits = null;
if (currentByte == 0)
{
// positive number
resultDigits = positiveDecimalDigits;
}
else
{
// negative number
List<byte> negativeDecimalDigits = new List<byte>(TwoToThePowerOf(absoluteBitNumber));
SubtractSecondDecimalFromFirst(negativeDecimalDigits, positiveDecimalDigits);
resultDigits = negativeDecimalDigits;
result.Append('-');
}
int d;
for (d = resultDigits.Count - 1; d >= 0; d--)
{
if (resultDigits[d] != 0)
break;
}
if (d < 0 && asn1.Length > 0)
{
// This is a special case where the result contains 0
result.Append(digitMap[0]);
}
else
{
while (d >= 0)
{
result.Append(digitMap[resultDigits[d--]]);
}
}
return result.ToString();
}
static byte[] TwoToThePowerOf(int n)
{
lock (powersOfTwo)
{
if (n >= powersOfTwo.Count)
{
for (int power = powersOfTwo.Count; power <= n; power++)
{
List<byte> decimalDigits = new List<byte>(powersOfTwo[power - 1]);
byte carryover = 0;
for (int i = 0; i < decimalDigits.Count; i++)
{
byte newValue = (byte)((decimalDigits[i] << 1) + carryover);
decimalDigits[i] = (byte)(newValue % 10);
carryover = (byte)(newValue / 10);
}
if (carryover > 0)
{
decimalDigits.Add(carryover);
carryover = 0;
}
powersOfTwo.Add(decimalDigits.ToArray());
}
}
return powersOfTwo[n];
}
}
static void AddSecondDecimalToFirst(List<byte> first, byte[] second)
{
byte carryover = 0;
for (int i = 0; i < second.Length || i < first.Count; i++)
{
if (i >= first.Count)
{
first.Add(0);
}
byte newValue;
if (i < second.Length)
{
newValue = (byte)(first[i] + second[i] + carryover);
}
else
{
newValue = (byte)(first[i] + carryover);
}
first[i] = (byte)(newValue % 10);
carryover = (byte)(newValue / 10);
}
if (carryover > 0)
{
first.Add(carryover);
}
}
static void SubtractSecondDecimalFromFirst(List<byte> first, List<byte> second)
{
byte borrow = 0;
for (int i = 0; i < second.Count; i++)
{
int newValue = first[i] - second[i] - borrow;
if (newValue < 0)
{
borrow = 1;
first[i] = (byte)(newValue + 10);
}
else
{
borrow = 0;
first[i] = (byte)newValue;
}
}
if (borrow > 0)
{
for (int i = second.Count; i < first.Count; i++)
{
int newValue = first[i] - borrow;
if (newValue < 0)
{
borrow = 1;
first[i] = (byte)(newValue + 10);
}
else
{
borrow = 0;
first[i] = (byte)newValue;
break;
}
}
}
DiagnosticUtility.DebugAssert(borrow == 0, "");
}
}
}

View File

@@ -0,0 +1,289 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel
{
using System;
using System.Diagnostics;
using System.Threading;
using System.Runtime;
/// <summary>
/// Base class for common AsyncResult programming scenarios.
/// </summary>
public abstract class AsyncResult : IAsyncResult, IDisposable
{
/// <summary>
/// End should be called when the End function for the asynchronous operation is complete. It
/// ensures the asynchronous operation is complete, and does some common validation.
/// </summary>
/// <param name="result">The <see cref="IAsyncResult"/> representing the status of an asynchronous operation.</param>
public static void End(IAsyncResult result)
{
if (result == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
AsyncResult asyncResult = result as AsyncResult;
if (asyncResult == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ID4001), "result"));
if (asyncResult.endCalled)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4002)));
asyncResult.endCalled = true;
if (!asyncResult.completed)
asyncResult.AsyncWaitHandle.WaitOne();
if (asyncResult.resetEvent != null)
((IDisposable)asyncResult.resetEvent).Dispose();
if (asyncResult.exception != null)
throw asyncResult.exception;
}
AsyncCallback callback;
bool completed;
bool completedSync;
bool disposed;
bool endCalled;
Exception exception;
ManualResetEvent resetEvent;
object state;
object thisLock;
/// <summary>
/// Constructor for async results that do not need a callback or state.
/// </summary>
protected AsyncResult()
: this(null, null)
{
}
/// <summary>
/// Constructor for async results that do not need a callback.
/// </summary>
/// <param name="state">A user-defined object that qualifies or contains information about an asynchronous operation.</param>
protected AsyncResult(object state)
: this(null, state)
{
}
/// <summary>
/// Constructor for async results that need a callback and a state.
/// </summary>
/// <param name="callback">The method to be called when the async operation completes.</param>
/// <param name="state">A user-defined object that qualifies or contains information about an asynchronous operation.</param>
protected AsyncResult(AsyncCallback callback, object state)
{
this.thisLock = new object();
this.callback = callback;
this.state = state;
}
/// <summary>
/// Finalizer for AsyncResult.
/// </summary>
~AsyncResult()
{
Dispose(false);
}
/// <summary>
/// Call this version of complete when your asynchronous operation is complete. This will update the state
/// of the operation and notify the callback.
/// </summary>
/// <param name="completedSynchronously">True if the asynchronous operation completed synchronously.</param>
protected void Complete(bool completedSynchronously)
{
Complete(completedSynchronously, null);
}
/// <summary>
/// Call this version of complete if you raise an exception during processing. In addition to notifying
/// the callback, it will capture the exception and store it to be thrown during AsyncResult.End.
/// </summary>
/// <param name="completedSynchronously">True if the asynchronous operation completed synchronously.</param>
/// <param name="exception">The exception during the processing of the asynchronous operation.</param>
protected void Complete(bool completedSynchronously, Exception exception)
{
if (completed == true)
{
// it is a bug to call complete twice
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AsynchronousOperationException(SR.GetString(SR.ID4005)));
}
completedSync = completedSynchronously;
this.exception = exception;
if (completedSynchronously)
{
//
// No event should be set for synchronous completion
//
completed = true;
Fx.Assert(resetEvent == null, SR.GetString(SR.ID8025));
}
else
{
//
// Complete asynchronously
//
lock (thisLock)
{
completed = true;
if (resetEvent != null)
resetEvent.Set();
}
}
//
// finally call the call back. Note, we are expecting user's callback to handle the exception
// so, if the callback throw exception, all we can do is burn and crash.
//
try
{
if (callback != null)
callback(this);
}
catch (ThreadAbortException)
{
//
// The thread running the callback is being aborted. We ignore this case.
//
}
catch (AsynchronousOperationException)
{
throw;
}
#pragma warning suppress 56500
catch (Exception unhandledException)
{
//
// The callback raising an exception is equivalent to Main raising an exception w/out a catch.
// We should just throw it back. We should log the exception somewhere.
//
// Because the stack trace gets lost on a rethrow, we're wrapping it in a generic exception
// so the stack trace is preserved.
//
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AsynchronousOperationException(SR.GetString(SR.ID4003), unhandledException));
}
}
/// <summary>
/// Disposes of unmanaged resources held by the AsyncResult.
/// </summary>
/// <param name="isExplicitDispose">True if this is an explicit call to Dispose.</param>
protected virtual void Dispose(bool isExplicitDispose)
{
if (!disposed)
{
if (isExplicitDispose)
{
lock (thisLock)
{
if (!disposed)
{
//
// Mark disposed
//
disposed = true;
//
// Called explicitly to close the object
//
if (resetEvent != null)
resetEvent.Close();
}
}
}
else
{
//
// Called for finalization
//
}
}
}
#region IAsyncResult implementation
/// <summary>
/// Gets the user-defined state information that was passed to the Begin method.
/// </summary>
public object AsyncState
{
get
{
return state;
}
}
/// <summary>
/// Gets the wait handle of the async event.
/// </summary>
public virtual WaitHandle AsyncWaitHandle
{
get
{
if (resetEvent == null)
{
bool savedCompleted = completed;
lock (thisLock)
{
if (resetEvent == null)
resetEvent = new ManualResetEvent(completed);
}
if (!savedCompleted && completed)
resetEvent.Set();
}
return resetEvent;
}
}
/// <summary>
/// Gets a value that indicates whether the asynchronous operation completed synchronously.
/// </summary>
public bool CompletedSynchronously
{
get
{
return completedSync;
}
}
/// <summary>
/// Gets a value that indicates whether the asynchronous operation has completed.
/// </summary>
public bool IsCompleted
{
get
{
return completed;
}
}
#endregion
#region IDisposable Members
/// <summary>
/// Disposes this object
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel
{
using System;
using System.Runtime.Serialization;
/// <summary>
/// This class defines the exception thrown during an asynchrous process.
/// </summary>
[Serializable]
public class AsynchronousOperationException : Exception
{
/// <summary>
/// Default constructor.
/// </summary>
public AsynchronousOperationException()
: base(SR.GetString(SR.ID4004))
{
}
/// <summary>
/// Constructor with message.
/// </summary>
/// <param name="message">The message describes what was causing the exception.</param>
public AsynchronousOperationException(string message)
: base(message)
{
}
/// <summary>
/// Constructor with message and inner exception.
/// </summary>
/// <param name="message">The message describes what was causing the exception.</param>
/// <param name="innerException">The inner exception indicates the real reason the exception was thrown.</param>
public AsynchronousOperationException(string message, Exception innerException)
: base(message, innerException)
{
}
/// <summary>
/// Constructor with inner exception.
/// </summary>
/// <param name="innerException">The inner exception indicates the real reason the exception was thrown.</param>
public AsynchronousOperationException(Exception innerException)
: base(SR.GetString(SR.ID4004), innerException)
{
}
/// <summary>
/// Constructor that sets the <see cref="SerializationInfo"/> with information about the exception.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/>. that contains contextual information about the source or destination.</param>
protected AsynchronousOperationException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

View File

@@ -0,0 +1,53 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel
{
using System;
using System.Runtime.Serialization;
/// <summary>
/// The specified RequestSecurityToken is not understood.
/// </summary>
[Serializable]
public class BadRequestException : RequestException
{
/// <summary>
/// Default constructor.
/// </summary>
public BadRequestException()
: base(SR.GetString(SR.ID2009))
{
}
/// <summary>
/// Constructor with message.
/// </summary>
/// <param name="message">The message describes what was causing the exception.</param>
public BadRequestException(string message)
: base(message)
{
}
/// <summary>
/// Constructor with message and inner exception.
/// </summary>
/// <param name="message">The message describes what was causing the exception.</param>
/// <param name="innerException">The inner exception indicates the real reason the exception was thrown.</param>
public BadRequestException(string message, Exception innerException)
: base(message, innerException)
{
}
/// <summary>
/// Constructor that sets the <see cref="SerializationInfo"/> with information about the exception.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/>. that contains contextual information about the source or destination.</param>
protected BadRequestException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

View File

@@ -0,0 +1,405 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
using System.Collections.Generic;
using System.Threading;
namespace System.IdentityModel
{
/// <summary>
/// A cache of type T where items are cached and removed
/// according to the type specified, currently only 'TimeBounded' is supported. An items is added with an expiration time.
/// </summary>
internal class BoundedCache<T> where T : class
{
Dictionary<string, ExpirableItem<T>> _items;
int _capacity;
TimeSpan _purgeInterval;
ReaderWriterLock _readWriteLock;
DateTime _nextPurgeTime = DateTime.UtcNow;
/// <summary>
/// Creates a cache for items of Type 'T' where expired items will purged on a regular interval
/// </summary>
/// <param name="capacity">The maximum size of the cache in number of items.
/// If int.MaxValue is passed then the size is not bound.</param>
/// <param name="purgeInterval">The time interval for checking expired items.</param>
///
public BoundedCache(int capacity, TimeSpan purgeInterval)
: this(capacity, purgeInterval, StringComparer.Ordinal)
{ }
/// <summary>
/// Creates a cache for items of Type 'T' where expired items will purged on a regular interval
/// </summary>
/// <param name="capacity">The maximum size of the cache in number of items.
/// If int.MaxValue is passed then the size is not bound.</param>
/// <param name="purgeInterval">The time interval for checking expired items.</param>
/// <param name="keyComparer">EqualityComparer for comparing keys.</param>
/// <exception cref="ArgumentOutOfRangeException">The input parameter 'capacity' is less than or equal to zero.</exception>
/// <exception cref="ArgumentOutOfRangeException">The input parameter 'purgeInterval' is less than or equal to TimeSpan.Zero.</exception>
/// <exception cref="ArgumentNullException">The input parameter 'keyComparer' is null.</exception>
public BoundedCache(int capacity, TimeSpan purgeInterval, IEqualityComparer<string> keyComparer)
{
if (capacity <= 0)
{
throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("capacity", capacity, SR.GetString(SR.ID0002));
}
if (purgeInterval <= TimeSpan.Zero)
{
throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("purgeInterval", purgeInterval, SR.GetString(SR.ID0016));
}
if (keyComparer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyComparer");
}
_capacity = capacity;
_purgeInterval = purgeInterval;
_items = new Dictionary<string, ExpirableItem<T>>(keyComparer);
_readWriteLock = new ReaderWriterLock();
}
/// <summary>
/// Gets the ReaderWriterLock for controlling simultaneous reads and writes
/// </summary>
protected ReaderWriterLock CacheLock
{
get
{
return _readWriteLock;
}
}
/// <summary>
/// Gets or Sets the current Capacity of the cache in number of items.
/// </summary>
public virtual int Capacity
{
get
{
return _capacity;
}
set
{
if (value <= 0)
{
throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("value", value, SR.GetString(SR.ID0002));
}
_capacity = value;
}
}
/// <summary>
/// Removes all items from the Cache.
/// </summary>
public virtual void Clear()
{
// -1 milleseconds is infinite timeout
_readWriteLock.AcquireWriterLock(TimeSpan.FromMilliseconds(-1));
try
{
_items.Clear();
}
finally
{
_readWriteLock.ReleaseWriterLock();
}
}
/// <summary>
/// Ensures that the maximum size is not exceeded
/// </summary>
/// <exception cref="LimitExceededException">If the Capacity of the cache has been reached.</exception>
void EnforceQuota()
{
// int.MaxValue => unbounded
if (_capacity == int.MaxValue)
{
return;
}
if (_items.Count >= _capacity)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new LimitExceededException(SR.GetString(SR.ID0021, _capacity)));
}
}
/// <summary>
/// Increases the maximum number of items that the cache will hold.
/// </summary>
/// <param name="size">The capacity to increase.</param>
/// <exception cref="ArgumentOutOfRangeException">The input parameter 'size' is less than or equal to zero.</exception>
/// <returns>Updated capacity</returns>
/// <remarks>If size + current capacity >= int.MaxValue then capacity will be set to int.MaxValue and the cache will be unbounded</remarks>
public virtual int IncreaseCapacity(int size)
{
if (size <= 0)
{
throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("size", size, SR.GetString(SR.ID0002));
}
// -1 milleseconds is infinite timeout
_readWriteLock.AcquireWriterLock(TimeSpan.FromMilliseconds(-1));
try
{
if (int.MaxValue - size <= _capacity)
{
_capacity = int.MaxValue;
}
else
{
_capacity = _capacity + size;
}
return _capacity;
}
finally
{
_readWriteLock.ReleaseWriterLock();
}
}
/// <summary>
/// Gets the Dictionary that contains the cached items.
/// </summary>
protected Dictionary<string, ExpirableItem<T>> Items
{
get
{
return _items;
}
}
/// <summary>
/// This method must not be called from within a read or writer lock as a deadlock will occur.
/// Checks the time a decides if a cleanup needs to occur.
/// </summary>
void Purge()
{
DateTime currentTime = DateTime.UtcNow;
if (currentTime < _nextPurgeTime)
{
return;
}
_nextPurgeTime = DateTimeUtil.Add(currentTime, _purgeInterval);
// -1 milleseconds is infinite timeout
_readWriteLock.AcquireWriterLock(TimeSpan.FromMilliseconds(-1));
try
{
List<string> expiredItems = new List<string>();
foreach (string key in _items.Keys)
{
if (_items[key].IsExpired())
{
expiredItems.Add(key);
}
}
for (int i = 0; i < expiredItems.Count; ++i)
{
_items.Remove(expiredItems[i]);
}
}
finally
{
_readWriteLock.ReleaseWriterLock();
}
}
/// <summary>
/// Gets or Sets the time interval that will be used for checking expired items.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">If 'value' is less than or equal to TimeSpan.Zero.</exception>
public TimeSpan PurgeInterval
{
get { return _purgeInterval; }
set
{
if (value <= TimeSpan.Zero)
{
throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("value", value, SR.GetString(SR.ID0016));
}
_purgeInterval = value;
}
}
/// <summary>
/// Attempt to add a item to the cache.
/// </summary>
/// <param name="key">Key to use when adding item</param>
/// <param name="item">Item of type 'T' to add to cache</param>
/// <param name="expirationTime">The expiration time of the entry.</param>
/// <returns>true if item was added, false if item was not added</returns>
/// <exception cref="LimitExceededException">Thrown if an attempt is made to add an item when the current
/// cache size is equal to the capacity</exception>
public virtual bool TryAdd(string key, T item, DateTime expirationTime)
{
Purge();
// -1 milleseconds is infinite timeout
_readWriteLock.AcquireWriterLock(TimeSpan.FromMilliseconds(-1));
EnforceQuota();
try
{
if (_items.ContainsKey(key))
{
return false;
}
else
{
_items[key] = new ExpirableItem<T>(item, expirationTime);
return true;
}
}
finally
{
_readWriteLock.ReleaseWriterLock();
}
}
/// <summary>
/// Attempts to find an item in the cache
/// </summary>
/// <param name="key">Item to search for.</param>
/// <returns>true if item is in cache, false otherwise</returns>
/// <remarks>Item may be expired and would be purged next cycle</remarks>
public virtual bool TryFind(string key)
{
Purge();
// -1 milleseconds is infinite timeout
_readWriteLock.AcquireReaderLock(TimeSpan.FromMilliseconds(-1));
try
{
if (_items.ContainsKey(key) && !_items[key].IsExpired())
{
return true;
}
return false;
}
finally
{
_readWriteLock.ReleaseReaderLock();
}
}
/// <summary>
/// Attempt to get an item from the Cache
/// </summary>
/// <param name="key">Item to seach for</param>
/// <param name="item">The object refernece that will be set the the retrivied item.</param>
/// <returns>true if item is found, false otherwise</returns>
/// <remarks>Item may be expired and would be purged next cycle</remarks>
public virtual bool TryGet(string key, out T item)
{
Purge();
item = null;
// -1 milleseconds is infinite timeout
_readWriteLock.AcquireReaderLock(TimeSpan.FromMilliseconds(-1));
try
{
if (_items.ContainsKey(key))
{
if (!_items[key].IsExpired())
{
item = _items[key].Item;
return true;
}
}
return false;
}
finally
{
_readWriteLock.ReleaseReaderLock();
}
}
/// <summary>
/// Attempts to remove an item from the Cache
/// </summary>
/// <param name="key">Item to remove</param>
/// <returns>true if item was removed, false otherwise</returns>
public virtual bool TryRemove(string key)
{
Purge();
// -1 milleseconds is infinite timeout
_readWriteLock.AcquireWriterLock(TimeSpan.FromMilliseconds(-1));
try
{
if (!_items.ContainsKey(key))
{
return false;
}
_items.Remove(key);
return true;
}
finally
{
_readWriteLock.ReleaseWriterLock();
}
}
/// <summary>
/// Wrapper class for objects contained in BoundedCache. Contains the obj 'T' and
/// </summary>
/// <typeparam name="ET">Type of the item</typeparam>
protected class ExpirableItem<ET>
{
DateTime _expirationTime;
ET _item;
public ExpirableItem(ET item, DateTime expirationTime)
{
_item = item;
if (expirationTime.Kind != DateTimeKind.Utc)
{
_expirationTime = DateTimeUtil.ToUniversalTime(expirationTime);
}
else
{
_expirationTime = expirationTime;
}
}
public bool IsExpired()
{
return (_expirationTime <= DateTime.UtcNow);
}
public ET Item
{
get { return _item; }
}
}
[Flags]
internal enum CachingMode
{
Time,
MRU,
FIFO
}
}
}

View File

@@ -0,0 +1,111 @@
//----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
namespace System.IdentityModel
{
using System;
using System.Runtime;
internal abstract class BufferManager
{
public abstract byte[] TakeBuffer(int bufferSize);
public abstract void ReturnBuffer(byte[] buffer);
public abstract void Clear();
public static BufferManager CreateBufferManager(long maxBufferPoolSize, int maxBufferSize)
{
if (maxBufferPoolSize < 0)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxBufferPoolSize",
maxBufferPoolSize, SR.GetString(SR.ValueMustBeNonNegative)));
}
if (maxBufferSize < 0)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxBufferSize",
maxBufferSize, SR.GetString(SR.ValueMustBeNonNegative)));
}
return new WrappingBufferManager(InternalBufferManager.Create(maxBufferPoolSize, maxBufferSize));
}
internal static InternalBufferManager GetInternalBufferManager(BufferManager bufferManager)
{
if (bufferManager is WrappingBufferManager)
{
return ((WrappingBufferManager)bufferManager).InternalBufferManager;
}
else
{
return new WrappingInternalBufferManager(bufferManager);
}
}
class WrappingBufferManager : BufferManager
{
InternalBufferManager innerBufferManager;
public WrappingBufferManager(InternalBufferManager innerBufferManager)
{
this.innerBufferManager = innerBufferManager;
}
public InternalBufferManager InternalBufferManager
{
get { return this.innerBufferManager; }
}
public override byte[] TakeBuffer(int bufferSize)
{
if (bufferSize < 0)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("bufferSize", bufferSize,
SR.GetString(SR.ValueMustBeNonNegative)));
}
return this.innerBufferManager.TakeBuffer(bufferSize);
}
public override void ReturnBuffer(byte[] buffer)
{
if (buffer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer");
}
this.innerBufferManager.ReturnBuffer(buffer);
}
public override void Clear()
{
this.innerBufferManager.Clear();
}
}
class WrappingInternalBufferManager : InternalBufferManager
{
BufferManager innerBufferManager;
public WrappingInternalBufferManager(BufferManager innerBufferManager)
{
this.innerBufferManager = innerBufferManager;
}
public override void Clear()
{
this.innerBufferManager.Clear();
}
public override void ReturnBuffer(byte[] buffer)
{
this.innerBufferManager.ReturnBuffer(buffer);
}
public override byte[] TakeBuffer(int bufferSize)
{
return this.innerBufferManager.TakeBuffer(bufferSize);
}
}
}
}

View File

@@ -0,0 +1,47 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel
{
using System;
using System.Runtime;
class BufferManagerOutputStream : BufferedOutputStream
{
string quotaExceededString;
public BufferManagerOutputStream(string quotaExceededString)
: base()
{
this.quotaExceededString = quotaExceededString;
}
public BufferManagerOutputStream(string quotaExceededString, int maxSize)
: base(maxSize)
{
this.quotaExceededString = quotaExceededString;
}
public BufferManagerOutputStream(string quotaExceededString, int initialSize, int maxSize, BufferManager bufferManager)
: base(initialSize, maxSize, BufferManager.GetInternalBufferManager(bufferManager))
{
this.quotaExceededString = quotaExceededString;
}
public void Init(int initialSize, int maxSizeQuota, BufferManager bufferManager)
{
Init(initialSize, maxSizeQuota, maxSizeQuota, bufferManager);
}
public void Init(int initialSize, int maxSizeQuota, int effectiveMaxSize, BufferManager bufferManager)
{
base.Reinitialize(initialSize, maxSizeQuota, effectiveMaxSize, BufferManager.GetInternalBufferManager(bufferManager));
}
protected override Exception CreateQuotaExceededException(int maxSizeQuota)
{
return new LimitExceededException(SR.GetString(this.quotaExceededString, maxSizeQuota));
}
}
}

View File

@@ -0,0 +1,95 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel
{
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
abstract class CanonicalFormWriter
{
internal static readonly UTF8Encoding Utf8WithoutPreamble = new UTF8Encoding(false);
protected static void Base64EncodeAndWrite(Stream stream, byte[] workBuffer, char[] base64WorkBuffer, byte[] data)
{
if ((data.Length / 3) * 4 + 4 > base64WorkBuffer.Length)
{
EncodeAndWrite(stream, Convert.ToBase64String(data));
return;
}
int encodedLength = Convert.ToBase64CharArray(data, 0, data.Length, base64WorkBuffer, 0, Base64FormattingOptions.None);
EncodeAndWrite(stream, workBuffer, base64WorkBuffer, encodedLength);
}
protected static void EncodeAndWrite(Stream stream, byte[] workBuffer, string s)
{
if (s.Length > workBuffer.Length)
{
EncodeAndWrite(stream, s);
return;
}
for (int i = 0; i < s.Length; i++)
{
char c = s[i];
if (c < 127)
{
workBuffer[i] = (byte) c;
}
else
{
EncodeAndWrite(stream, s);
return;
}
}
stream.Write(workBuffer, 0, s.Length);
}
protected static void EncodeAndWrite(Stream stream, byte[] workBuffer, char[] chars)
{
EncodeAndWrite(stream, workBuffer, chars, chars.Length);
}
protected static void EncodeAndWrite(Stream stream, byte[] workBuffer, char[] chars, int count)
{
if (count > workBuffer.Length)
{
EncodeAndWrite(stream, chars, count);
return;
}
for (int i = 0; i < count; i++)
{
char c = chars[i];
if (c < 127)
{
workBuffer[i] = (byte) c;
}
else
{
EncodeAndWrite(stream, chars, count);
return;
}
}
stream.Write(workBuffer, 0, count);
}
static void EncodeAndWrite(Stream stream, string s)
{
byte[] buffer = CanonicalFormWriter.Utf8WithoutPreamble.GetBytes(s);
stream.Write(buffer, 0, buffer.Length);
}
static void EncodeAndWrite(Stream stream, char[] chars, int count)
{
byte[] buffer = CanonicalFormWriter.Utf8WithoutPreamble.GetBytes(chars, 0, count);
stream.Write(buffer, 0, buffer.Length);
}
}
}

View File

@@ -0,0 +1,144 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel
{
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
sealed class CanonicalizationDriver
{
bool closeReadersAfterProcessing;
XmlReader reader;
string[] inclusivePrefixes;
bool includeComments;
public bool CloseReadersAfterProcessing
{
get { return this.closeReadersAfterProcessing; }
set { this.closeReadersAfterProcessing = value; }
}
public bool IncludeComments
{
get { return this.includeComments; }
set { this.includeComments = value; }
}
public string[] GetInclusivePrefixes()
{
return this.inclusivePrefixes;
}
public void Reset()
{
this.reader = null;
}
public void SetInclusivePrefixes(string[] inclusivePrefixes)
{
this.inclusivePrefixes = inclusivePrefixes;
}
public void SetInput(Stream stream)
{
if (stream == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("stream");
}
this.reader = XmlReader.Create(stream);
}
public void SetInput(XmlReader reader)
{
if (reader == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
}
this.reader = reader;
}
public byte[] GetBytes()
{
return GetMemoryStream().ToArray();
}
public MemoryStream GetMemoryStream()
{
MemoryStream stream = new MemoryStream();
WriteTo(stream);
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
public void WriteTo(HashAlgorithm hashAlgorithm)
{
WriteTo(new HashStream(hashAlgorithm));
}
public void WriteTo(Stream canonicalStream)
{
if (this.reader != null)
{
XmlDictionaryReader dicReader = this.reader as XmlDictionaryReader;
if ((dicReader != null) && (dicReader.CanCanonicalize))
{
dicReader.MoveToContent();
dicReader.StartCanonicalization(canonicalStream, this.includeComments, this.inclusivePrefixes);
dicReader.Skip();
dicReader.EndCanonicalization();
}
else
{
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(Stream.Null);
if (this.inclusivePrefixes != null)
{
// Add a dummy element at the top and populate the namespace
// declaration of all the inclusive prefixes.
writer.WriteStartElement("a", reader.LookupNamespace(String.Empty));
for (int i = 0; i < this.inclusivePrefixes.Length; ++i)
{
string ns = reader.LookupNamespace(this.inclusivePrefixes[i]);
if (ns != null)
{
writer.WriteXmlnsAttribute(this.inclusivePrefixes[i], ns);
}
}
}
writer.StartCanonicalization(canonicalStream, this.includeComments, this.inclusivePrefixes);
if (reader is WrappedReader)
{
((WrappedReader)reader).XmlTokens.GetWriter().WriteTo(writer, new DictionaryManager());
}
else
{
writer.WriteNode(reader, false);
}
writer.Flush();
writer.EndCanonicalization();
if (this.inclusivePrefixes != null)
writer.WriteEndElement();
writer.Close();
}
if (this.closeReadersAfterProcessing)
{
this.reader.Close();
}
this.reader = null;
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoInputIsSetForCanonicalization)));
}
}
}
}

View File

@@ -0,0 +1,84 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel
{
using System;
using System.Xml;
internal class CipherDataElement
{
byte[] _iv;
byte[] _cipherText;
public byte[] CipherValue
{
get
{
if ( _iv != null )
{
byte[] buffer = new byte[_iv.Length + _cipherText.Length];
Buffer.BlockCopy( _iv, 0, buffer, 0, _iv.Length );
Buffer.BlockCopy( _cipherText, 0, buffer, _iv.Length, _cipherText.Length );
_iv = null;
}
return _cipherText;
}
set
{
_cipherText = value;
}
}
public void ReadXml( XmlDictionaryReader reader )
{
if ( reader == null )
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "reader" );
}
reader.MoveToContent();
if ( !reader.IsStartElement( XmlEncryptionConstants.Elements.CipherData, XmlEncryptionConstants.Namespace ) )
{
throw DiagnosticUtility.ThrowHelperXml( reader, SR.GetString( SR.ID4188 ) );
}
reader.ReadStartElement( XmlEncryptionConstants.Elements.CipherData, XmlEncryptionConstants.Namespace );
reader.ReadStartElement( XmlEncryptionConstants.Elements.CipherValue, XmlEncryptionConstants.Namespace );
_cipherText = reader.ReadContentAsBase64();
_iv = null;
// <CipherValue>
reader.MoveToContent();
reader.ReadEndElement();
// <CipherData>
reader.MoveToContent();
reader.ReadEndElement();
}
public void SetCipherValueFragments( byte[] iv, byte[] cipherText )
{
_iv = iv;
_cipherText = cipherText;
}
public void WriteXml( XmlWriter writer )
{
writer.WriteStartElement( XmlEncryptionConstants.Prefix, XmlEncryptionConstants.Elements.CipherData, XmlEncryptionConstants.Namespace );
writer.WriteStartElement( XmlEncryptionConstants.Prefix, XmlEncryptionConstants.Elements.CipherValue, XmlEncryptionConstants.Namespace );
if ( _iv != null )
writer.WriteBase64( _iv, 0, _iv.Length );
writer.WriteBase64( _cipherText, 0, _cipherText.Length );
writer.WriteEndElement(); // CipherValue
writer.WriteEndElement(); // CipherData
}
}
}

View File

@@ -0,0 +1,73 @@
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
using System.Collections.ObjectModel;
using System.IdentityModel.Tokens;
namespace System.Security.Claims
{
/// <summary>
/// The authentication information that an authority asserted when creating a token for a subject.
/// </summary>
public class AuthenticationInformation
{
string _address;
Collection<AuthenticationContext> _authContexts;
string _dnsName;
DateTime? _notOnOrAfter;
string _session;
/// <summary>
/// Initializes a new instance of the <see cref="AuthenticationInformation"/> class.
/// </summary>
public AuthenticationInformation()
{
_authContexts = new Collection<AuthenticationContext>();
}
/// <summary>
/// Gets or sets the address of the authority that created the token.
/// </summary>
public string Address
{
get { return _address; }
set { _address = value; }
}
/// <summary>
/// Gets the <see cref="AuthorizationContext"/> used by the authenticating authority when issuing tokens.
/// </summary>
public Collection<AuthenticationContext> AuthorizationContexts
{
get { return _authContexts; }
}
/// <summary>
/// Gets or sets the DNS name of the authority that created the token.
/// </summary>
public string DnsName
{
get { return _dnsName; }
set { _dnsName = value; }
}
/// <summary>
/// Gets or sets the time that the session referred to in the session index MUST be considered ended.
/// </summary>
public DateTime? NotOnOrAfter
{
get { return _notOnOrAfter; }
set { _notOnOrAfter = value; }
}
/// <summary>
/// Gets or sets the session index that describes the session between the authority and the client.
/// </summary>
public string Session
{
get { return _session; }
set { _session = value; }
}
}
}

View File

@@ -0,0 +1,94 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Claims;
using System.IdentityModel.Tokens;
namespace System.Security.Claims
{
internal static class AuthenticationTypeMaps
{
public struct Mapping
{
public Mapping( string normalized, string unnormalized )
{
Normalized = normalized;
Unnormalized = unnormalized;
}
public string Normalized;
public string Unnormalized;
}
public static Mapping[] Saml = new Mapping[]
{
new Mapping( AuthenticationMethods.HardwareToken, SamlConstants.AuthenticationMethods.HardwareTokenString ),
new Mapping( AuthenticationMethods.Kerberos, SamlConstants.AuthenticationMethods.KerberosString ),
new Mapping( AuthenticationMethods.Password, SamlConstants.AuthenticationMethods.PasswordString ),
new Mapping( AuthenticationMethods.Pgp, SamlConstants.AuthenticationMethods.PgpString ),
new Mapping( AuthenticationMethods.SecureRemotePassword, SamlConstants.AuthenticationMethods.SecureRemotePasswordString ),
new Mapping( AuthenticationMethods.Signature, SamlConstants.AuthenticationMethods.SignatureString ),
new Mapping( AuthenticationMethods.Spki, SamlConstants.AuthenticationMethods.SpkiString ),
new Mapping( AuthenticationMethods.TlsClient, SamlConstants.AuthenticationMethods.TlsClientString ),
new Mapping( AuthenticationMethods.Unspecified, SamlConstants.AuthenticationMethods.UnspecifiedString ),
new Mapping( AuthenticationMethods.Windows, SamlConstants.AuthenticationMethods.WindowsString ),
new Mapping( AuthenticationMethods.X509, SamlConstants.AuthenticationMethods.X509String ),
new Mapping( AuthenticationMethods.Xkms, SamlConstants.AuthenticationMethods.XkmsString ),
};
public static Mapping[] Saml2 = new Mapping[]
{
new Mapping( AuthenticationMethods.Kerberos, Saml2Constants.AuthenticationContextClasses.KerberosString ),
new Mapping( AuthenticationMethods.Password, Saml2Constants.AuthenticationContextClasses.PasswordString ),
new Mapping( AuthenticationMethods.Pgp, Saml2Constants.AuthenticationContextClasses.PgpString ),
new Mapping( AuthenticationMethods.SecureRemotePassword, Saml2Constants.AuthenticationContextClasses.SecureRemotePasswordString ),
new Mapping( AuthenticationMethods.Signature, Saml2Constants.AuthenticationContextClasses.XmlDsigString ),
new Mapping( AuthenticationMethods.Spki, Saml2Constants.AuthenticationContextClasses.SpkiString ),
new Mapping( AuthenticationMethods.Smartcard, Saml2Constants.AuthenticationContextClasses.SmartcardString ),
new Mapping( AuthenticationMethods.SmartcardPki, Saml2Constants.AuthenticationContextClasses.SmartcardPkiString ),
new Mapping( AuthenticationMethods.TlsClient, Saml2Constants.AuthenticationContextClasses.TlsClientString ),
new Mapping( AuthenticationMethods.Unspecified, Saml2Constants.AuthenticationContextClasses.UnspecifiedString ),
new Mapping( AuthenticationMethods.X509, Saml2Constants.AuthenticationContextClasses.X509String ),
new Mapping( AuthenticationMethods.Windows, Saml2Constants.AuthenticationContextClasses.WindowsString ),
};
/// <summary>
/// Returns the protocol specific value matching a normalized value.
/// </summary>
/// <remarks>
/// If no match is found, the original value is returned.
/// </remarks>
public static string Denormalize( string normalizedAuthenticationMethod, Mapping[] mappingTable )
{
foreach ( Mapping mapping in mappingTable )
{
if (StringComparer.Ordinal.Equals( normalizedAuthenticationMethod, mapping.Normalized ) )
return mapping.Unnormalized;
}
return normalizedAuthenticationMethod;
}
/// <summary>
/// Returns the normalized value matching a protocol specific value.
/// </summary>
/// <remarks>
/// If no match is found, the original value is returned.
/// </remarks>
public static string Normalize( string unnormalizedAuthenticationMethod, Mapping[] mappingTable )
{
foreach ( Mapping mapping in mappingTable )
{
if ( StringComparer.Ordinal.Equals( unnormalizedAuthenticationMethod, mapping.Unnormalized ) )
return mapping.Normalized;
}
return unnormalizedAuthenticationMethod;
}
}
}

View File

@@ -0,0 +1,27 @@
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
namespace System.Security.Claims
{
/// <summary>
/// Defines types for WindowsIdentity AuthenticationType
/// </summary>
public static class AuthenticationTypes
{
#pragma warning disable 1591
public const string Basic = "Basic";
public const string Federation = "Federation";
public const string Kerberos = "Kerberos";
public const string Negotiate = "Negotiate";
public const string Password = "Password";
public const string Signature = "Signature";
public const string Windows = "Windows";
public const string X509 = "X509";
#pragma warning restore 1591
// Types generated by CLR WindowsIdentity:
// :generated by NTAuthenticationInfoClass: NTLM, Kerberos, WDigest, Negotiate
// :generated by GetServerVariable("AUTH_TYPE"): Basic, Digest, Kerberos, NTLM, and RADIUS
}
}

View File

@@ -0,0 +1,104 @@
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IdentityModel;
namespace System.Security.Claims
{
/// <summary>
/// This class is used to specify the context of the authorization event.
/// </summary>
public class AuthorizationContext
{
Collection<System.Security.Claims.Claim> _action = new Collection<System.Security.Claims.Claim>();
Collection<System.Security.Claims.Claim> _resource = new Collection<System.Security.Claims.Claim>();
ClaimsPrincipal _principal;
/// <summary>
/// Creates an AuthorizationContext with the specified principal, resource, and action.
/// </summary>
/// <param name="principal">The principal to be authorized.</param>
/// <param name="resource">The resource to be authorized for.</param>
/// <param name="action">The action to be performed on the resource.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="principal"/> or <paramref name="resource"/> is set to null.
/// </exception>
public AuthorizationContext( ClaimsPrincipal principal, string resource, string action )
{
if ( principal == null )
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "principal" );
}
if ( string.IsNullOrEmpty( resource ) )
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "resource" );
}
_principal = principal;
_resource.Add( new System.Security.Claims.Claim( ClaimTypes.Name, resource ) );
if ( action != null )
{
_action.Add( new System.Security.Claims.Claim( ClaimTypes.Name, action ) );
}
}
/// <summary>
/// Creates an AuthorizationContext with the specified principal, resource, and action.
/// </summary>
/// <param name="principal">The principal to check authorization for</param>
/// <param name="resource">The resource for checking authorization to</param>
/// <param name="action">The action to be performed on the resource</param>
/// <exception cref="ArgumentNullException">When <paramref name="principal"/> or <paramref name="resource"/> or <paramref name="action"/> is null</exception>
public AuthorizationContext( ClaimsPrincipal principal, Collection<System.Security.Claims.Claim> resource, Collection<System.Security.Claims.Claim> action )
{
if ( principal == null )
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "principal" );
}
if ( resource == null )
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "resource" );
}
if ( action == null )
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "action" );
}
_principal = principal;
_resource = resource;
_action = action;
}
/// <summary>
/// Gets the authorization action
/// </summary>
public Collection<System.Security.Claims.Claim> Action
{
get { return _action; }
}
/// <summary>
/// Gets the authorization resource
/// </summary>
public Collection<System.Security.Claims.Claim> Resource
{
get { return _resource; }
}
/// <summary>
/// Gets the authorization principal
/// </summary>
public ClaimsPrincipal Principal
{
get { return _principal; }
}
}
}

View File

@@ -0,0 +1,221 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel.Claims
{
using System.Collections.Generic;
using System.Globalization;
using System.Net.Mail;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
// Examples:
// ClaimType ResourceValue ResourceRight
// --------------- ---------------- ------------------
// "File" "boot.ini" "Read"
// "HairColor" "Brown" "PossessProperty"
// "UserName" "[....]" "PossessProperty"
// "Service" "MailService" "Access"
// "Operation" "ReadMail" "Invoke"
// ClaimType:
// DESC: The type of resource for which rights are granted
// XrML: ClaimSet/Resource
// SAML: SamlAttributeStatement/Attribute/@Name/..., SamlAuthorizationDecisionStatement/Action/@Namespace/...
// ResourceValue:
// DESC: Value identifying the resource for which rights are granted
// XrML: ClaimSet/Resource/...
// SAML: SamlAttributeStatement/Attribute/..., SamlAuthorizationDecisionStatement/@Resource/...
// Right:
// DESC: Rights expressed about a resource
// XRML: ClaimSet/Right
// SAML: SamlAttributeStatement (aka. "PossessProperty") or, SamlAuthorizationDecisionStatement/Action/...
[DataContract(Namespace = XsiConstants.Namespace)]
public class Claim
{
static Claim system;
[DataMember(Name = "ClaimType")]
string claimType;
[DataMember(Name = "Resource")]
object resource;
[DataMember(Name = "Right")]
string right;
IEqualityComparer<Claim> comparer;
Claim(string claimType, object resource, string right, IEqualityComparer<Claim> comparer)
{
if (claimType == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claimType");
if (claimType.Length <= 0)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("claimType", SR.GetString(SR.ArgumentCannotBeEmptyString));
if (right == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("right");
if (right.Length <= 0)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("right", SR.GetString(SR.ArgumentCannotBeEmptyString));
this.claimType = StringUtil.OptimizeString(claimType);
this.resource = resource;
this.right = StringUtil.OptimizeString(right);
this.comparer = comparer;
}
public Claim(string claimType, object resource, string right) : this(claimType, resource, right, null)
{
}
public static IEqualityComparer<Claim> DefaultComparer
{
get
{
return EqualityComparer<Claim>.Default;
}
}
public static Claim System
{
get
{
if (system == null)
system = new Claim(ClaimTypes.System, XsiConstants.System, Rights.Identity);
return system;
}
}
public object Resource
{
get { return this.resource; }
}
public string ClaimType
{
get { return this.claimType; }
}
public string Right
{
get { return this.right; }
}
// Turn key claims
public static Claim CreateDnsClaim(string dns)
{
if (dns == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dns");
return new Claim(ClaimTypes.Dns, dns, Rights.PossessProperty, ClaimComparer.Dns);
}
public static Claim CreateDenyOnlyWindowsSidClaim(SecurityIdentifier sid)
{
if (sid == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sid");
return new Claim(ClaimTypes.DenyOnlySid, sid, Rights.PossessProperty);
}
public static Claim CreateHashClaim(byte[] hash)
{
if (hash == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("hash");
return new Claim(ClaimTypes.Hash, SecurityUtils.CloneBuffer(hash), Rights.PossessProperty, ClaimComparer.Hash);
}
public static Claim CreateMailAddressClaim(MailAddress mailAddress)
{
if (mailAddress == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("mailAddress");
return new Claim(ClaimTypes.Email, mailAddress, Rights.PossessProperty);
}
public static Claim CreateNameClaim(string name)
{
if (name == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("name");
return new Claim(ClaimTypes.Name, name, Rights.PossessProperty);
}
public static Claim CreateRsaClaim(RSA rsa)
{
if (rsa == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rsa");
return new Claim(ClaimTypes.Rsa, rsa, Rights.PossessProperty, ClaimComparer.Rsa);
}
public static Claim CreateSpnClaim(string spn)
{
if (spn == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("spn");
return new Claim(ClaimTypes.Spn, spn, Rights.PossessProperty);
}
public static Claim CreateThumbprintClaim(byte[] thumbprint)
{
if (thumbprint == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("thumbprint");
return new Claim(ClaimTypes.Thumbprint, SecurityUtils.CloneBuffer(thumbprint), Rights.PossessProperty, ClaimComparer.Thumbprint);
}
public static Claim CreateUpnClaim(string upn)
{
if (upn == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("upn");
return new Claim(ClaimTypes.Upn, upn, Rights.PossessProperty, ClaimComparer.Upn);
}
public static Claim CreateUriClaim(Uri uri)
{
if (uri == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri");
return new Claim(ClaimTypes.Uri, uri, Rights.PossessProperty);
}
public static Claim CreateWindowsSidClaim(SecurityIdentifier sid)
{
if (sid == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sid");
return new Claim(ClaimTypes.Sid, sid, Rights.PossessProperty);
}
public static Claim CreateX500DistinguishedNameClaim(X500DistinguishedName x500DistinguishedName)
{
if (x500DistinguishedName == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("x500DistinguishedName");
return new Claim(ClaimTypes.X500DistinguishedName, x500DistinguishedName, Rights.PossessProperty, ClaimComparer.X500DistinguishedName);
}
public override bool Equals(object obj)
{
if (comparer == null)
comparer = ClaimComparer.GetComparer(this.claimType);
return comparer.Equals(this, obj as Claim);
}
public override int GetHashCode()
{
if (comparer == null)
comparer = ClaimComparer.GetComparer(this.claimType);
return comparer.GetHashCode(this);
}
public override string ToString()
{
return string.Format(CultureInfo.CurrentCulture, "{0}: {1}", this.right, this.claimType);
}
}
}

View File

@@ -0,0 +1,351 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel.Claims
{
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
class ClaimComparer : IEqualityComparer<Claim>
{
static IEqualityComparer<Claim> defaultComparer;
static IEqualityComparer<Claim> hashComparer;
static IEqualityComparer<Claim> dnsComparer;
static IEqualityComparer<Claim> rsaComparer;
static IEqualityComparer<Claim> thumbprintComparer;
static IEqualityComparer<Claim> upnComparer;
static IEqualityComparer<Claim> x500DistinguishedNameComparer;
IEqualityComparer resourceComparer;
ClaimComparer(IEqualityComparer resourceComparer)
{
this.resourceComparer = resourceComparer;
}
public static IEqualityComparer<Claim> GetComparer(string claimType)
{
if (claimType == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claimType");
if (claimType == ClaimTypes.Dns)
return Dns;
if (claimType == ClaimTypes.Hash)
return Hash;
if (claimType == ClaimTypes.Rsa)
return Rsa;
if (claimType == ClaimTypes.Thumbprint)
return Thumbprint;
if (claimType == ClaimTypes.Upn)
return Upn;
if (claimType == ClaimTypes.X500DistinguishedName)
return X500DistinguishedName;
return Default;
}
public static IEqualityComparer<Claim> Default
{
get
{
if (defaultComparer == null)
{
defaultComparer = new ClaimComparer(new ObjectComparer());
}
return defaultComparer;
}
}
public static IEqualityComparer<Claim> Dns
{
get
{
if (dnsComparer == null)
{
dnsComparer = new ClaimComparer(StringComparer.OrdinalIgnoreCase);
}
return dnsComparer;
}
}
public static IEqualityComparer<Claim> Hash
{
get
{
if (hashComparer == null)
{
hashComparer = new ClaimComparer(new BinaryObjectComparer());
}
return hashComparer;
}
}
public static IEqualityComparer<Claim> Rsa
{
get
{
if (rsaComparer == null)
{
rsaComparer = new ClaimComparer(new RsaObjectComparer());
}
return rsaComparer;
}
}
public static IEqualityComparer<Claim> Thumbprint
{
get
{
if (thumbprintComparer == null)
{
thumbprintComparer = new ClaimComparer(new BinaryObjectComparer());
}
return thumbprintComparer;
}
}
public static IEqualityComparer<Claim> Upn
{
get
{
if (upnComparer == null)
{
upnComparer = new ClaimComparer(new UpnObjectComparer());
}
return upnComparer;
}
}
public static IEqualityComparer<Claim> X500DistinguishedName
{
get
{
if (x500DistinguishedNameComparer == null)
{
x500DistinguishedNameComparer = new ClaimComparer(new X500DistinguishedNameObjectComparer());
}
return x500DistinguishedNameComparer;
}
}
// we still need to review how the default equals works, this is not how Doug envisioned it.
public bool Equals(Claim claim1, Claim claim2)
{
if (ReferenceEquals(claim1, claim2))
return true;
if (claim1 == null || claim2 == null)
return false;
if (claim1.ClaimType != claim2.ClaimType || claim1.Right != claim2.Right)
return false;
return resourceComparer.Equals(claim1.Resource, claim2.Resource);
}
public int GetHashCode(Claim claim)
{
if (claim == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claim");
return claim.ClaimType.GetHashCode() ^ claim.Right.GetHashCode()
^ ( (claim.Resource == null) ? 0 : resourceComparer.GetHashCode(claim.Resource));
}
class ObjectComparer : IEqualityComparer
{
bool IEqualityComparer.Equals(object obj1, object obj2)
{
if (obj1 == null && obj2 == null)
return true;
if (obj1 == null || obj2 == null)
return false;
return obj1.Equals(obj2);
}
int IEqualityComparer.GetHashCode(object obj)
{
if (obj == null)
return 0;
return obj.GetHashCode();
}
}
class BinaryObjectComparer : IEqualityComparer
{
bool IEqualityComparer.Equals(object obj1, object obj2)
{
if (ReferenceEquals(obj1, obj2))
return true;
byte[] bytes1 = obj1 as byte[];
byte[] bytes2 = obj2 as byte[];
if (bytes1 == null || bytes2 == null)
return false;
if (bytes1.Length != bytes2.Length)
return false;
for (int i = 0; i < bytes1.Length; ++i)
{
if (bytes1[i] != bytes2[i])
return false;
}
return true;
}
int IEqualityComparer.GetHashCode(object obj)
{
byte[] bytes = obj as byte[];
if (bytes == null)
return 0;
int hashCode = 0;
for (int i = 0; i < bytes.Length && i < 4; ++i)
{
hashCode = (hashCode << 8) | bytes[i];
}
return hashCode ^ bytes.Length;
}
}
class RsaObjectComparer : IEqualityComparer
{
bool IEqualityComparer.Equals(object obj1, object obj2)
{
if (ReferenceEquals(obj1, obj2))
return true;
RSA rsa1 = obj1 as RSA;
RSA rsa2 = obj2 as RSA;
if (rsa1 == null || rsa2 == null)
return false;
RSAParameters parm1 = rsa1.ExportParameters(false);
RSAParameters parm2 = rsa2.ExportParameters(false);
if (parm1.Modulus.Length != parm2.Modulus.Length ||
parm1.Exponent.Length != parm2.Exponent.Length)
return false;
for (int i = 0; i < parm1.Modulus.Length; ++i)
{
if (parm1.Modulus[i] != parm2.Modulus[i])
return false;
}
for (int i = 0; i < parm1.Exponent.Length; ++i)
{
if (parm1.Exponent[i] != parm2.Exponent[i])
return false;
}
return true;
}
int IEqualityComparer.GetHashCode(object obj)
{
RSA rsa = obj as RSA;
if (rsa == null)
return 0;
RSAParameters parm = rsa.ExportParameters(false);
return parm.Modulus.Length ^ parm.Exponent.Length;
}
}
class X500DistinguishedNameObjectComparer : IEqualityComparer
{
IEqualityComparer binaryComparer;
public X500DistinguishedNameObjectComparer()
{
binaryComparer = new BinaryObjectComparer();
}
bool IEqualityComparer.Equals(object obj1, object obj2)
{
if (ReferenceEquals(obj1, obj2))
return true;
X500DistinguishedName dn1 = obj1 as X500DistinguishedName;
X500DistinguishedName dn2 = obj2 as X500DistinguishedName;
if (dn1 == null || dn2 == null)
return false;
// 1) Hopefully cover most cases (perf reason).
if (StringComparer.Ordinal.Equals(dn1.Name, dn2.Name))
return true;
// 2) Raw byte compare. Note: we assume the rawbyte is in the same order
// (default = X500DistinguishedNameFlags.Reversed).
return binaryComparer.Equals(dn1.RawData, dn2.RawData);
}
int IEqualityComparer.GetHashCode(object obj)
{
X500DistinguishedName dn = obj as X500DistinguishedName;
if (dn == null)
return 0;
return binaryComparer.GetHashCode(dn.RawData);
}
}
class UpnObjectComparer : IEqualityComparer
{
bool IEqualityComparer.Equals(object obj1, object obj2)
{
if (StringComparer.OrdinalIgnoreCase.Equals(obj1, obj2))
return true;
string upn1 = obj1 as string;
string upn2 = obj2 as string;
if (upn1 == null || upn2 == null)
return false;
SecurityIdentifier sid1;
if (!TryLookupSidFromName(upn1, out sid1))
return false;
// Normalize to sid
SecurityIdentifier sid2;
if (!TryLookupSidFromName(upn2, out sid2))
return false;
return sid1 == sid2;
}
int IEqualityComparer.GetHashCode(object obj)
{
string upn = obj as string;
if (upn == null)
return 0;
// Normalize to sid
SecurityIdentifier sid;
if (TryLookupSidFromName(upn, out sid))
return sid.GetHashCode();
return StringComparer.OrdinalIgnoreCase.GetHashCode(upn);
}
bool TryLookupSidFromName(string upn, out SecurityIdentifier sid)
{
sid = null;
try
{
NTAccount acct = new NTAccount(upn);
sid = acct.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier;
}
catch (IdentityNotMappedException e)
{
DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
}
return sid != null;
}
}
}
}

View File

@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
namespace System.Security.Claims
{
/// <summary>
/// Defines the keys for properties contained in <see cref="Claim.Properties"/>.
/// </summary>
public static class ClaimProperties
{
#pragma warning disable 1591
public const string Namespace = "http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties";
public const string SamlAttributeDisplayName = Namespace + "/displayname";
public const string SamlAttributeNameFormat = Namespace + "/attributename";
public const string SamlNameIdentifierFormat = Namespace + "/format";
public const string SamlNameIdentifierNameQualifier = Namespace + "/namequalifier";
public const string SamlNameIdentifierSPNameQualifier = Namespace + "/spnamequalifier";
public const string SamlNameIdentifierSPProvidedId = Namespace + "/spprovidedid";
#pragma warning restore 1591
}
}

View File

@@ -0,0 +1,115 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel.Claims
{
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Security.Principal;
using System.Text;
[DataContract(Namespace = XsiConstants.Namespace)]
public abstract class ClaimSet : IEnumerable<Claim>
{
static ClaimSet system;
static ClaimSet windows;
static ClaimSet anonymous;
public static ClaimSet System
{
get
{
if (system == null)
{
List<Claim> claims = new List<Claim>(2);
claims.Add(Claim.System);
claims.Add(new Claim(ClaimTypes.System, XsiConstants.System, Rights.PossessProperty));
system = new DefaultClaimSet(claims);
}
return system;
}
}
public static ClaimSet Windows
{
get
{
if (windows == null)
{
List<Claim> claims = new List<Claim>(2);
SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.NTAuthoritySid, null);
claims.Add(new Claim(ClaimTypes.Sid, sid, Rights.Identity));
claims.Add(Claim.CreateWindowsSidClaim(sid));
windows = new DefaultClaimSet(claims);
}
return windows;
}
}
internal static ClaimSet Anonymous
{
get
{
if (anonymous == null)
anonymous = new DefaultClaimSet();
return anonymous;
}
}
static internal bool SupportedRight(string right)
{
return right == null ||
Rights.Identity.Equals(right) ||
Rights.PossessProperty.Equals(right);
}
public virtual bool ContainsClaim(Claim claim, IEqualityComparer<Claim> comparer)
{
if (claim == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claim");
if (comparer == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("comparer");
IEnumerable<Claim> claims = FindClaims(null, null);
if (claims != null)
{
foreach (Claim matchingClaim in claims)
{
if (comparer.Equals(claim, matchingClaim))
return true;
}
}
return false;
}
public virtual bool ContainsClaim(Claim claim)
{
if (claim == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claim");
IEnumerable<Claim> claims = FindClaims(claim.ClaimType, claim.Right);
if (claims != null)
{
foreach (Claim matchingClaim in claims)
{
if (claim.Equals(matchingClaim))
return true;
}
}
return false;
}
public abstract Claim this[int index] { get; }
public abstract int Count { get; }
public abstract ClaimSet Issuer { get; }
// Note: null string represents any.
public abstract IEnumerable<Claim> FindClaims(string claimType, string right);
public abstract IEnumerator<Claim> GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
}
}

View File

@@ -0,0 +1,78 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel.Claims
{
public static class ClaimTypes
{
const string claimTypeNamespace = XsiConstants.Namespace + "/claims";
const string anonymous = claimTypeNamespace + "/anonymous";
const string dns = claimTypeNamespace + "/dns";
const string email = claimTypeNamespace + "/emailaddress";
const string hash = claimTypeNamespace + "/hash";
const string name = claimTypeNamespace + "/name";
const string rsa = claimTypeNamespace + "/rsa";
const string sid = claimTypeNamespace + "/sid";
const string denyOnlySid = claimTypeNamespace + "/denyonlysid";
const string spn = claimTypeNamespace + "/spn";
const string system = claimTypeNamespace + "/system";
const string thumbprint = claimTypeNamespace + "/thumbprint";
const string upn = claimTypeNamespace + "/upn";
const string uri = claimTypeNamespace + "/uri";
const string x500DistinguishedName = claimTypeNamespace + "/x500distinguishedname";
const string givenname = claimTypeNamespace + "/givenname";
const string surname = claimTypeNamespace + "/surname";
const string streetaddress = claimTypeNamespace + "/streetaddress";
const string locality = claimTypeNamespace + "/locality";
const string stateorprovince = claimTypeNamespace + "/stateorprovince";
const string postalcode = claimTypeNamespace + "/postalcode";
const string country = claimTypeNamespace + "/country";
const string homephone = claimTypeNamespace + "/homephone";
const string otherphone = claimTypeNamespace + "/otherphone";
const string mobilephone = claimTypeNamespace + "/mobilephone";
const string dateofbirth = claimTypeNamespace + "/dateofbirth";
const string gender = claimTypeNamespace + "/gender";
const string ppid = claimTypeNamespace + "/privatepersonalidentifier";
const string webpage = claimTypeNamespace + "/webpage";
const string nameidentifier = claimTypeNamespace + "/nameidentifier";
const string authentication = claimTypeNamespace + "/authentication";
const string authorizationdecision = claimTypeNamespace + "/authorizationdecision";
static public string Anonymous { get { return anonymous; } }
static public string DenyOnlySid { get { return denyOnlySid; } }
static public string Dns { get { return dns; } }
static public string Email { get { return email; } }
static public string Hash { get { return hash; } }
static public string Name { get { return name; } }
static public string Rsa { get { return rsa; } }
static public string Sid { get { return sid; } }
static public string Spn { get { return spn; } }
static public string System { get { return system; } }
static public string Thumbprint { get { return thumbprint; } }
static public string Upn { get { return upn; } }
static public string Uri { get { return uri; } }
static public string X500DistinguishedName { get { return x500DistinguishedName; } }
static public string NameIdentifier { get { return nameidentifier; } }
static public string Authentication { get { return authentication; } }
static public string AuthorizationDecision { get { return authorizationdecision; } }
// used in info card
static public string GivenName { get { return givenname; } }
static public string Surname { get { return surname; } }
static public string StreetAddress { get { return streetaddress; } }
static public string Locality { get { return locality; } }
static public string StateOrProvince { get { return stateorprovince; } }
static public string PostalCode { get { return postalcode; } }
static public string Country { get { return country; } }
static public string HomePhone { get { return homephone; } }
static public string OtherPhone { get { return otherphone; } }
static public string MobilePhone { get { return mobilephone; } }
static public string DateOfBirth { get { return dateofbirth; } }
static public string Gender { get { return gender; } }
static public string PPID { get { return ppid; } }
static public string Webpage { get { return webpage; } }
}
}

View File

@@ -0,0 +1,37 @@
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
using System.IdentityModel;
using System.IdentityModel.Configuration;
using System.Xml;
namespace System.Security.Claims
{
/// <summary>
/// A Simple ClaimsAuthenticationManager that echoes back the incoming ClaimsIdentities.
/// </summary>
public class ClaimsAuthenticationManager : ICustomIdentityConfiguration
{
/// <summary>
/// The method echoes back the incoming ClaimsIdentities.
/// </summary>
/// <param name="resourceName">The address to which the request was sent.</param>
/// <param name="incomingPrincipal"><see cref="ClaimsPrincipal"/> presented by the client (in the form of a
/// SecurityToken) to access the resource.</param>
/// <returns>The ClaimsPrincipal given to the method.</returns>
public virtual ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
return incomingPrincipal;
}
/// <summary>
/// Load custom configuration from Xml
/// </summary>
/// <param name="nodelist">Custom configuration elements</param>
public virtual void LoadCustomConfiguration(XmlNodeList nodelist)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException(SR.GetString(SR.ID0023, this.GetType().AssemblyQualifiedName)));
}
}
}

Some files were not shown because too many files have changed in this diff Show More