summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.InfoCard/InfoCard
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2013-06-16 16:58:19 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2013-06-16 16:58:19 -0700
commitcccc7a63b9abeed1f075a35a532e25d52c1d89db (patch)
treeb6e249316b69d2ea7ad1652ecb9f2bdebf892577 /src/DotNetOpenAuth.InfoCard/InfoCard
parent89c2167a677ebb23aca7f1e9592af7954a093fff (diff)
downloadDotNetOpenAuth-cccc7a63b9abeed1f075a35a532e25d52c1d89db.zip
DotNetOpenAuth-cccc7a63b9abeed1f075a35a532e25d52c1d89db.tar.gz
DotNetOpenAuth-cccc7a63b9abeed1f075a35a532e25d52c1d89db.tar.bz2
Removes InfoCard support from the library.
InfoCard support has been removed from recent versions of Windows. It's effectively dead.
Diffstat (limited to 'src/DotNetOpenAuth.InfoCard/InfoCard')
-rw-r--r--src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.Designer.cs117
-rw-r--r--src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.resx138
-rw-r--r--src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.sr.resx135
-rw-r--r--src/DotNetOpenAuth.InfoCard/InfoCard/Token/InformationCardException.cs62
-rw-r--r--src/DotNetOpenAuth.InfoCard/InfoCard/Token/Token.cs269
-rw-r--r--src/DotNetOpenAuth.InfoCard/InfoCard/Token/TokenDecryptor.cs209
-rw-r--r--src/DotNetOpenAuth.InfoCard/InfoCard/Token/TokenUtility.cs302
-rw-r--r--src/DotNetOpenAuth.InfoCard/InfoCard/WellKnownClaimTypes.cs269
-rw-r--r--src/DotNetOpenAuth.InfoCard/InfoCard/WellKnownIssuers.cs23
9 files changed, 0 insertions, 1524 deletions
diff --git a/src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.Designer.cs b/src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.Designer.cs
deleted file mode 100644
index a6d3dcf..0000000
--- a/src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.Designer.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-// This code was generated by a tool.
-// Runtime Version:4.0.30104.0
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace DotNetOpenAuth.InfoCard {
- using System;
-
-
- /// <summary>
- /// A strongly-typed resource class, for looking up localized strings, etc.
- /// </summary>
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class InfoCardStrings {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal InfoCardStrings() {
- }
-
- /// <summary>
- /// Returns the cached ResourceManager instance used by this class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetOpenAuth.InfoCard.InfoCardStrings", typeof(InfoCardStrings).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- /// <summary>
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The token is invalid: The audience restrictions does not match the Relying Party..
- /// </summary>
- internal static string AudienceMismatch {
- get {
- return ResourceManager.GetString("AudienceMismatch", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The list of claims requested for inclusion in the InfoCard must be non-empty..
- /// </summary>
- internal static string EmptyClaimListNotAllowed {
- get {
- return ResourceManager.GetString("EmptyClaimListNotAllowed", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Failed to find the encryptionAlgorithm..
- /// </summary>
- internal static string EncryptionAlgorithmNotFound {
- get {
- return ResourceManager.GetString("EncryptionAlgorithmNotFound", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to This operation requires the PPID claim to be included in the InfoCard token..
- /// </summary>
- internal static string PpidClaimRequired {
- get {
- return ResourceManager.GetString("PpidClaimRequired", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The PrivacyVersion property must be set whenever the PrivacyUrl property is set..
- /// </summary>
- internal static string PrivacyVersionRequiredWithPrivacyUrl {
- get {
- return ResourceManager.GetString("PrivacyVersionRequiredWithPrivacyUrl", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to Click here to select your Information Card..
- /// </summary>
- internal static string SelectorClickPrompt {
- get {
- return ResourceManager.GetString("SelectorClickPrompt", resourceCulture);
- }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.resx b/src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.resx
deleted file mode 100644
index 956b321..0000000
--- a/src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.resx
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">2.0</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- <value>[base64 mime encoded serialized .NET Framework object]</value>
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
- <comment>This is a comment</comment>
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" use="required" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <data name="AudienceMismatch" xml:space="preserve">
- <value>The token is invalid: The audience restrictions does not match the Relying Party.</value>
- </data>
- <data name="EmptyClaimListNotAllowed" xml:space="preserve">
- <value>The list of claims requested for inclusion in the InfoCard must be non-empty.</value>
- </data>
- <data name="EncryptionAlgorithmNotFound" xml:space="preserve">
- <value>Failed to find the encryptionAlgorithm.</value>
- </data>
- <data name="PpidClaimRequired" xml:space="preserve">
- <value>This operation requires the PPID claim to be included in the InfoCard token.</value>
- </data>
- <data name="PrivacyVersionRequiredWithPrivacyUrl" xml:space="preserve">
- <value>The PrivacyVersion property must be set whenever the PrivacyUrl property is set.</value>
- </data>
- <data name="SelectorClickPrompt" xml:space="preserve">
- <value>Click here to select your Information Card.</value>
- </data>
-</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.sr.resx b/src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.sr.resx
deleted file mode 100644
index 9df0429..0000000
--- a/src/DotNetOpenAuth.InfoCard/InfoCard/InfoCardStrings.sr.resx
+++ /dev/null
@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">2.0</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- <value>[base64 mime encoded serialized .NET Framework object]</value>
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
- <comment>This is a comment</comment>
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" use="required" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <data name="AudienceMismatch" xml:space="preserve">
- <value>Token je neispravan: restrikcije u prijemu se ne slažu sa Relying Party.</value>
- </data>
- <data name="EmptyClaimListNotAllowed" xml:space="preserve">
- <value>Tražena lista zahteva za uključivanje u InfoCard ne sme biti prazna.</value>
- </data>
- <data name="EncryptionAlgorithmNotFound" xml:space="preserve">
- <value>encryptionAlgorithm nije pronađen.</value>
- </data>
- <data name="PpidClaimRequired" xml:space="preserve">
- <value>Ova operacija zahteva da PPID zahtev bude uključen u InfoCard token.</value>
- </data>
- <data name="SelectorClickPrompt" xml:space="preserve">
- <value>Kliknite ovde da odaberete vaš Information Card.</value>
- </data>
-</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.InfoCard/InfoCard/Token/InformationCardException.cs b/src/DotNetOpenAuth.InfoCard/InfoCard/Token/InformationCardException.cs
deleted file mode 100644
index d718964..0000000
--- a/src/DotNetOpenAuth.InfoCard/InfoCard/Token/InformationCardException.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="InformationCardException.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.InfoCard {
- using System;
- using System.Runtime.Serialization;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// An exception class for Information Cards.
- /// </summary>
- [Serializable]
- public class InformationCardException : ProtocolException {
- /// <summary>
- /// Initializes a new instance of the <see cref="InformationCardException"/> class.
- /// </summary>
- public InformationCardException() {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="InformationCardException"/> class with a specified
- /// error message.
- /// </summary>
- /// <param name="message">The error message.</param>
- public InformationCardException(string message)
- : base(message) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="InformationCardException"/> class
- /// with a specified error message and a reference to the inner exception that is
- /// the cause of this exception.
- /// </summary>
- /// <param name="message">The error message that explains the reason for the exception.</param>
- /// <param name="innerException">
- /// The exception that is the cause of the current exception, or a null reference
- /// (Nothing in Visual Basic) if no inner exception is specified.
- /// </param>
- public InformationCardException(string message, Exception innerException)
- : base(message, innerException) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="InformationCardException"/> class
- /// with serialized data.
- /// </summary>
- /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
- /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
- /// <exception cref="T:System.ArgumentNullException">
- /// The <paramref name="info"/> parameter is null.
- /// </exception>
- /// <exception cref="T:System.Runtime.Serialization.SerializationException">
- /// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
- /// </exception>
- protected InformationCardException(SerializationInfo info, StreamingContext context)
- : base(info, context) {
- }
- }
-} \ No newline at end of file
diff --git a/src/DotNetOpenAuth.InfoCard/InfoCard/Token/Token.cs b/src/DotNetOpenAuth.InfoCard/InfoCard/Token/Token.cs
deleted file mode 100644
index 2ac1788..0000000
--- a/src/DotNetOpenAuth.InfoCard/InfoCard/Token/Token.cs
+++ /dev/null
@@ -1,269 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="Token.cs" company="Outercurve Foundation, Microsoft Corporation">
-// Copyright (c) Outercurve Foundation, Microsoft Corporation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.InfoCard {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.IdentityModel.Claims;
- using System.IdentityModel.Policy;
- using System.IdentityModel.Tokens;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Xml;
- using System.Xml.XPath;
- using DotNetOpenAuth.Messaging;
- using Validation;
-
- /// <summary>
- /// The decrypted token that was submitted as an Information Card.
- /// </summary>
- public class Token {
- /// <summary>
- /// Backing field for the <see cref="Claims"/> property.
- /// </summary>
- private IDictionary<string, string> claims;
-
- /// <summary>
- /// Backing field for the <see cref="UniqueId"/> property.
- /// </summary>
- private string uniqueId;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Token"/> class.
- /// </summary>
- /// <param name="tokenXml">Xml token, which may be encrypted.</param>
- /// <param name="audience">The audience. May be <c>null</c> to avoid audience checking.</param>
- /// <param name="decryptor">The decryptor to use to decrypt the token, if necessary..</param>
- /// <exception cref="InformationCardException">Thrown for any problem decoding or decrypting the token.</exception>
- [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Not a problem for this type."), SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive")]
- private Token(string tokenXml, Uri audience, TokenDecryptor decryptor) {
- Requires.NotNullOrEmpty(tokenXml, "tokenXml");
- Requires.That(decryptor != null || !IsEncrypted(tokenXml), "decryptor", "Required when tokenXml is encrypted.");
-
- byte[] decryptedBytes;
- string decryptedString;
-
- using (StringReader xmlReader = new StringReader(tokenXml)) {
- var readerSettings = MessagingUtilities.CreateUntrustedXmlReaderSettings();
- using (XmlReader tokenReader = XmlReader.Create(xmlReader, readerSettings)) {
- Assumes.True(tokenReader != null); // BCL contract should say XmlReader.Create result != null
- if (IsEncrypted(tokenReader)) {
- Logger.InfoCard.DebugFormat("Incoming SAML token, before decryption: {0}", tokenXml);
- decryptedBytes = decryptor.DecryptToken(tokenReader);
- decryptedString = Encoding.UTF8.GetString(decryptedBytes);
- Assumes.True(decryptedString != null); // BCL contracts should be enhanced here
- } else {
- decryptedBytes = Encoding.UTF8.GetBytes(tokenXml);
- decryptedString = tokenXml;
- }
- }
- }
-
- var stringReader = new StringReader(decryptedString);
- try {
- this.Xml = new XPathDocument(stringReader).CreateNavigator();
- } catch {
- stringReader.Dispose();
- throw;
- }
-
- Logger.InfoCard.DebugFormat("Incoming SAML token, after any decryption: {0}", this.Xml.InnerXml);
- this.AuthorizationContext = TokenUtility.AuthenticateToken(this.Xml.ReadSubtree(), audience);
- }
-
- /// <summary>
- /// Gets the AuthorizationContext behind this token.
- /// </summary>
- public AuthorizationContext AuthorizationContext { get; private set; }
-
- /// <summary>
- /// Gets the the decrypted token XML.
- /// </summary>
- public XPathNavigator Xml { get; private set; }
-
- /// <summary>
- /// Gets the UniqueID of this token, usable as a stable username that the user
- /// has already verified belongs to him/her.
- /// </summary>
- /// <remarks>
- /// By default, this uses the PPID and the Issuer's Public Key and hashes them
- /// together to generate a UniqueID.
- /// </remarks>
- public string UniqueId {
- get {
- if (string.IsNullOrEmpty(this.uniqueId)) {
- this.uniqueId = TokenUtility.GetUniqueName(this.AuthorizationContext);
- }
-
- return this.uniqueId;
- }
- }
-
- /// <summary>
- /// Gets the hash of the card issuer's public key.
- /// </summary>
- public string IssuerPubKeyHash {
- get { return TokenUtility.GetIssuerPubKeyHash(this.AuthorizationContext); }
- }
-
- /// <summary>
- /// Gets the Site Specific ID that the user sees in the Identity Selector.
- /// </summary>
- public string SiteSpecificId {
- get {
- RequiresEx.ValidState(this.Claims.ContainsKey(ClaimTypes.PPID) && !string.IsNullOrEmpty(this.Claims[ClaimTypes.PPID]));
- string ppidValue;
- ErrorUtilities.VerifyOperation(this.Claims.TryGetValue(ClaimTypes.PPID, out ppidValue) && ppidValue != null, InfoCardStrings.PpidClaimRequired);
- return TokenUtility.CalculateSiteSpecificID(ppidValue);
- }
- }
-
- /// <summary>
- /// Gets the claims in all the claimsets as a dictionary of strings.
- /// </summary>
- public IDictionary<string, string> Claims {
- get {
- if (this.claims == null) {
- this.claims = this.GetFlattenedClaims();
- }
-
- return this.claims;
- }
- }
-
- /// <summary>
- /// Deserializes an XML document into a token.
- /// </summary>
- /// <param name="tokenXml">The token XML.</param>
- /// <returns>The deserialized token.</returns>
- public static Token Read(string tokenXml) {
- Requires.NotNullOrEmpty(tokenXml, "tokenXml");
- return Read(tokenXml, (Uri)null);
- }
-
- /// <summary>
- /// Deserializes an XML document into a token.
- /// </summary>
- /// <param name="tokenXml">The token XML.</param>
- /// <param name="audience">The URI that this token must have been crafted to be sent to. Use <c>null</c> to accept any intended audience.</param>
- /// <returns>The deserialized token.</returns>
- public static Token Read(string tokenXml, Uri audience) {
- Requires.NotNullOrEmpty(tokenXml, "tokenXml");
- return Read(tokenXml, audience, Enumerable.Empty<SecurityToken>());
- }
-
- /// <summary>
- /// Deserializes an XML document into a token.
- /// </summary>
- /// <param name="tokenXml">The token XML.</param>
- /// <param name="decryptionTokens">Any X.509 certificates that may be used to decrypt the token, if necessary.</param>
- /// <returns>The deserialized token.</returns>
- public static Token Read(string tokenXml, IEnumerable<SecurityToken> decryptionTokens) {
- Requires.NotNullOrEmpty(tokenXml, "tokenXml");
- Requires.NotNull(decryptionTokens, "decryptionTokens");
- return Read(tokenXml, null, decryptionTokens);
- }
-
- /// <summary>
- /// Deserializes an XML document into a token.
- /// </summary>
- /// <param name="tokenXml">The token XML.</param>
- /// <param name="audience">The URI that this token must have been crafted to be sent to. Use <c>null</c> to accept any intended audience.</param>
- /// <param name="decryptionTokens">Any X.509 certificates that may be used to decrypt the token, if necessary.</param>
- /// <returns>The deserialized token.</returns>
- public static Token Read(string tokenXml, Uri audience, IEnumerable<SecurityToken> decryptionTokens) {
- Requires.NotNullOrEmpty(tokenXml, "tokenXml");
- Requires.NotNull(decryptionTokens, "decryptionTokens");
-
- TokenDecryptor decryptor = null;
-
- if (IsEncrypted(tokenXml)) {
- decryptor = new TokenDecryptor();
- decryptor.Tokens.AddRange(decryptionTokens);
- }
-
- return new Token(tokenXml, audience, decryptor);
- }
-
- /// <summary>
- /// Determines whether the specified token XML is encrypted.
- /// </summary>
- /// <param name="tokenXml">The token XML.</param>
- /// <returns>
- /// <c>true</c> if the specified token XML is encrypted; otherwise, <c>false</c>.
- /// </returns>
- [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive"), Pure]
- internal static bool IsEncrypted(string tokenXml) {
- Requires.NotNull(tokenXml, "tokenXml");
-
- var stringReader = new StringReader(tokenXml);
- XmlReader tokenReader;
- try {
- var readerSettings = MessagingUtilities.CreateUntrustedXmlReaderSettings();
- tokenReader = XmlReader.Create(stringReader, readerSettings);
- } catch {
- stringReader.Dispose();
- throw;
- }
-
- try {
- Assumes.True(tokenReader != null); // CC missing for XmlReader.Create
- return IsEncrypted(tokenReader);
- } catch {
- IDisposable disposableReader = tokenReader;
- disposableReader.Dispose();
- throw;
- }
- }
-
- /// <summary>
- /// Determines whether the specified token XML is encrypted.
- /// </summary>
- /// <param name="tokenXmlReader">The token XML.</param>
- /// <returns>
- /// <c>true</c> if the specified token XML is encrypted; otherwise, <c>false</c>.
- /// </returns>
- private static bool IsEncrypted(XmlReader tokenXmlReader) {
- Requires.NotNull(tokenXmlReader, "tokenXmlReader");
- return tokenXmlReader.IsStartElement(TokenDecryptor.XmlEncryptionStrings.EncryptedData, TokenDecryptor.XmlEncryptionStrings.Namespace);
- }
-
-#if CONTRACTS_FULL
- /// <summary>
- /// Verifies conditions that should be true for any valid state of this object.
- /// </summary>
- [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
- [ContractInvariantMethod]
- private void ObjectInvariant() {
- Contract.Invariant(this.AuthorizationContext != null);
- }
-#endif
-
- /// <summary>
- /// Flattens the claims into a dictionary
- /// </summary>
- /// <returns>A dictionary of claim type URIs and claim values.</returns>
- [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Expensive call.")]
- [Pure]
- private IDictionary<string, string> GetFlattenedClaims() {
- var flattenedClaims = new Dictionary<string, string>();
-
- foreach (ClaimSet set in this.AuthorizationContext.ClaimSets) {
- foreach (Claim claim in set) {
- if (claim.Right == Rights.PossessProperty) {
- flattenedClaims.Add(claim.ClaimType, TokenUtility.GetResourceValue(claim));
- }
- }
- }
-
- return flattenedClaims;
- }
- }
-}
diff --git a/src/DotNetOpenAuth.InfoCard/InfoCard/Token/TokenDecryptor.cs b/src/DotNetOpenAuth.InfoCard/InfoCard/Token/TokenDecryptor.cs
deleted file mode 100644
index fab5148..0000000
--- a/src/DotNetOpenAuth.InfoCard/InfoCard/Token/TokenDecryptor.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="TokenDecryptor.cs" company="Microsoft Corporation">
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// </copyright>
-// <license>
-// Microsoft Public License (Ms-PL).
-// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL
-// </license>
-// <author>This file was subsequently modified by Andrew Arnott.</author>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.InfoCard {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.IdentityModel.Selectors;
- using System.IdentityModel.Tokens;
- using System.Linq;
- using System.Security.Cryptography;
- using System.Security.Cryptography.X509Certificates;
- using System.ServiceModel.Security;
- using System.Xml;
- using DotNetOpenAuth.Messaging;
- using Validation;
-
- /// <summary>
- /// A utility class for decrypting InfoCard tokens.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Decryptor", Justification = "By design")]
- internal class TokenDecryptor {
- /// <summary>
- /// Backing field for the <see cref="Tokens"/> property.
- /// </summary>
- private List<SecurityToken> tokens;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="TokenDecryptor"/> class.
- /// </summary>
- internal TokenDecryptor() {
- this.tokens = new List<SecurityToken>();
- StoreName storeName = StoreName.My;
- StoreLocation storeLocation = StoreLocation.LocalMachine;
- this.AddDecryptionCertificates(storeName, storeLocation);
- }
-
- /// <summary>
- /// Gets a list of possible decryption certificates, from the store/location set
- /// </summary>
- /// <remarks>
- /// Defaults to localmachine:my (same place SSL certs are)
- /// </remarks>
- internal List<SecurityToken> Tokens {
- get { return this.tokens; }
- }
-
- /// <summary>
- /// Adds a certificate to the list of certificates to decrypt with.
- /// </summary>
- /// <param name="certificate">The x509 cert to use for decryption</param>
- internal void AddDecryptionCertificate(X509Certificate2 certificate) {
- this.Tokens.Add(new X509SecurityToken(certificate));
- }
-
- /// <summary>
- /// Adds a certificate to the list of certificates to decrypt with.
- /// </summary>
- /// <param name="storeName">store name of the certificate</param>
- /// <param name="storeLocation">store location</param>
- /// <param name="thumbprint">thumbprint of the cert to use</param>
- internal void AddDecryptionCertificate(StoreName storeName, StoreLocation storeLocation, string thumbprint) {
- this.AddDecryptionCertificates(
- storeName,
- storeLocation,
- store => store.Find(X509FindType.FindByThumbprint, thumbprint, true));
- }
-
- /// <summary>
- /// Adds a store of certificates to the list of certificates to decrypt with.
- /// </summary>
- /// <param name="storeName">store name of the certificates</param>
- /// <param name="storeLocation">store location</param>
- internal void AddDecryptionCertificates(StoreName storeName, StoreLocation storeLocation) {
- this.AddDecryptionCertificates(storeName, storeLocation, store => store);
- }
-
- /// <summary>
- /// Decrpyts a security token from an XML EncryptedData
- /// </summary>
- /// <param name="reader">The encrypted token XML reader.</param>
- /// <returns>A byte array of the contents of the encrypted token</returns>
- internal byte[] DecryptToken(XmlReader reader) {
- Requires.NotNull(reader, "reader");
-
- byte[] securityTokenData;
- string encryptionAlgorithm;
- SecurityKeyIdentifier keyIdentifier;
- bool isEmptyElement;
-
- ErrorUtilities.VerifyInternal(reader.IsStartElement(XmlEncryptionStrings.EncryptedData, XmlEncryptionStrings.Namespace), "Expected encrypted token starting XML element was not found.");
- reader.Read(); // get started
-
- // if it's not an encryption method, something is dreadfully wrong.
- InfoCardErrorUtilities.VerifyInfoCard(reader.IsStartElement(XmlEncryptionStrings.EncryptionMethod, XmlEncryptionStrings.Namespace), InfoCardStrings.EncryptionAlgorithmNotFound);
-
- // Looks good, let's grab the alg.
- isEmptyElement = reader.IsEmptyElement;
- encryptionAlgorithm = reader.GetAttribute(XmlEncryptionStrings.Algorithm);
- reader.Read();
-
- if (!isEmptyElement) {
- while (reader.IsStartElement()) {
- reader.Skip();
- }
- reader.ReadEndElement();
- }
-
- // get the key identifier
- keyIdentifier = WSSecurityTokenSerializer.DefaultInstance.ReadKeyIdentifier(reader);
-
- // resolve the symmetric key
- SymmetricSecurityKey decryptingKey = (SymmetricSecurityKey)SecurityTokenResolver.CreateDefaultSecurityTokenResolver(this.tokens.AsReadOnly(), false).ResolveSecurityKey(keyIdentifier[0]);
- SymmetricAlgorithm algorithm = decryptingKey.GetSymmetricAlgorithm(encryptionAlgorithm);
-
- // dig for the security token data itself.
- reader.ReadStartElement(XmlEncryptionStrings.CipherData, XmlEncryptionStrings.Namespace);
- reader.ReadStartElement(XmlEncryptionStrings.CipherValue, XmlEncryptionStrings.Namespace);
- securityTokenData = Convert.FromBase64String(reader.ReadString());
- reader.ReadEndElement(); // CipherValue
- reader.ReadEndElement(); // CipherData
- reader.ReadEndElement(); // EncryptedData
-
- // decrypto-magic!
- int blockSizeBytes = algorithm.BlockSize / 8;
- byte[] iv = new byte[blockSizeBytes];
- Buffer.BlockCopy(securityTokenData, 0, iv, 0, iv.Length);
- algorithm.Padding = PaddingMode.ISO10126;
- algorithm.Mode = CipherMode.CBC;
- ICryptoTransform decrTransform = algorithm.CreateDecryptor(algorithm.Key, iv);
- byte[] plainText = decrTransform.TransformFinalBlock(securityTokenData, iv.Length, securityTokenData.Length - iv.Length);
- decrTransform.Dispose();
-
- return plainText;
- }
-
-#if CONTRACTS_FULL
- /// <summary>
- /// Verifies conditions that should be true for any valid state of this object.
- /// </summary>
- [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
- [ContractInvariantMethod]
- private void ObjectInvariant() {
- Contract.Invariant(this.Tokens != null);
- }
-#endif
-
- /// <summary>
- /// Adds a store of certificates to the list of certificates to decrypt with.
- /// </summary>
- /// <param name="storeName">store name of the certificates</param>
- /// <param name="storeLocation">store location</param>
- /// <param name="filter">A filter to on the certificates to add.</param>
- private void AddDecryptionCertificates(StoreName storeName, StoreLocation storeLocation, Func<X509Certificate2Collection, X509Certificate2Collection> filter) {
- X509Store store = new X509Store(storeName, storeLocation);
- store.Open(OpenFlags.ReadOnly);
-
- this.tokens.AddRange((from cert in filter(store.Certificates).Cast<X509Certificate2>()
- where cert.HasPrivateKey
- select new X509SecurityToken(cert)).Cast<SecurityToken>());
-
- store.Close();
- }
-
- /// <summary>
- /// A set of strings used in parsing the XML token.
- /// </summary>
- internal static class XmlEncryptionStrings {
- /// <summary>
- /// The "http://www.w3.org/2001/04/xmlenc#" value.
- /// </summary>
- internal const string Namespace = "http://www.w3.org/2001/04/xmlenc#";
-
- /// <summary>
- /// The "EncryptionMethod" value.
- /// </summary>
- internal const string EncryptionMethod = "EncryptionMethod";
-
- /// <summary>
- /// The "CipherValue" value.
- /// </summary>
- internal const string CipherValue = "CipherValue";
-
- /// <summary>
- /// The "Algorithm" value.
- /// </summary>
- internal const string Algorithm = "Algorithm";
-
- /// <summary>
- /// The "EncryptedData" value.
- /// </summary>
- internal const string EncryptedData = "EncryptedData";
-
- /// <summary>
- /// The "CipherData" value.
- /// </summary>
- internal const string CipherData = "CipherData";
- }
- }
-} \ No newline at end of file
diff --git a/src/DotNetOpenAuth.InfoCard/InfoCard/Token/TokenUtility.cs b/src/DotNetOpenAuth.InfoCard/InfoCard/Token/TokenUtility.cs
deleted file mode 100644
index 616cb9f..0000000
--- a/src/DotNetOpenAuth.InfoCard/InfoCard/Token/TokenUtility.cs
+++ /dev/null
@@ -1,302 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="TokenUtility.cs" company="Microsoft Corporation">
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// </copyright>
-// <license>
-// Microsoft Public License (Ms-PL).
-// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL
-// </license>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.InfoCard {
- using System;
- using System.Collections.Generic;
- using System.Configuration;
- using System.Diagnostics.CodeAnalysis;
- using System.IdentityModel.Claims;
- using System.IdentityModel.Policy;
- using System.IdentityModel.Selectors;
- using System.IdentityModel.Tokens;
- using System.IO;
- using System.Linq;
- using System.Net.Mail;
- using System.Security.Cryptography;
- using System.Security.Principal;
- using System.ServiceModel.Security;
- using System.Text;
- using System.Xml;
- using DotNetOpenAuth.Messaging;
- using Validation;
-
- /// <summary>
- /// Tools for reading InfoCard tokens.
- /// </summary>
- internal static class TokenUtility {
- /// <summary>
- /// Gets the maximum amount the token can be out of sync with time.
- /// </summary>
- internal static TimeSpan MaximumClockSkew {
- get { return DotNetOpenAuth.Configuration.DotNetOpenAuthSection.Messaging.MaximumClockSkew; }
- }
-
- /// <summary>
- /// Token Authentication. Translates the decrypted data into a AuthContext.
- /// </summary>
- /// <param name="reader">The token XML reader.</param>
- /// <param name="audience">The audience that the token must be scoped for.
- /// Use <c>null</c> to indicate any audience is acceptable.</param>
- /// <returns>
- /// The authorization context carried by the token.
- /// </returns>
- internal static AuthorizationContext AuthenticateToken(XmlReader reader, Uri audience) {
- // Extensibility Point:
- // in order to accept different token types, you would need to add additional
- // code to create an authenticationcontext from the security token.
- // This code only supports SamlSecurityToken objects.
- SamlSecurityToken token = WSSecurityTokenSerializer.DefaultInstance.ReadToken(reader, null) as SamlSecurityToken;
-
- if (null == token) {
- throw new InformationCardException("Unable to read security token");
- }
-
- if (null != token.SecurityKeys && token.SecurityKeys.Count > 0) {
- throw new InformationCardException("Token Security Keys Exist");
- }
-
- if (audience == null) {
- Logger.InfoCard.Warn("SAML token Audience checking will be skipped.");
- } else {
- if (token.Assertion.Conditions != null &&
- token.Assertion.Conditions.Conditions != null) {
- foreach (SamlCondition condition in token.Assertion.Conditions.Conditions) {
- SamlAudienceRestrictionCondition audienceCondition = condition as SamlAudienceRestrictionCondition;
-
- if (audienceCondition != null) {
- Logger.InfoCard.DebugFormat("SAML token audience(s): {0}", audienceCondition.Audiences.ToStringDeferred());
- bool match = audienceCondition.Audiences.Contains(audience);
-
- if (!match && Logger.InfoCard.IsErrorEnabled) {
- Logger.InfoCard.ErrorFormat("Expected SAML token audience of {0} but found {1}.", audience.AbsoluteUri, audienceCondition.Audiences.Select(aud => aud.AbsoluteUri).ToStringDeferred());
- }
-
- // The token is invalid if any condition is not valid.
- // An audience restriction condition is valid if any audience
- // matches the Relying Party.
- InfoCardErrorUtilities.VerifyInfoCard(match, InfoCardStrings.AudienceMismatch);
- }
- }
- }
- }
- var samlAuthenticator = new SamlSecurityTokenAuthenticator(
- new List<SecurityTokenAuthenticator>(
- new SecurityTokenAuthenticator[] {
- new RsaSecurityTokenAuthenticator(),
- new X509SecurityTokenAuthenticator(),
- }),
- MaximumClockSkew);
-
- if (audience != null) {
- samlAuthenticator.AllowedAudienceUris.Add(audience.AbsoluteUri);
- }
-
- return AuthorizationContext.CreateDefaultAuthorizationContext(samlAuthenticator.ValidateToken(token));
- }
-
- /// <summary>
- /// Translates claims to strings
- /// </summary>
- /// <param name="claim">Claim to translate to a string</param>
- /// <returns>The string representation of a claim's value.</returns>
- [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive.")]
- internal static string GetResourceValue(Claim claim) {
- string strClaim = claim.Resource as string;
- if (!string.IsNullOrEmpty(strClaim)) {
- return strClaim;
- }
-
- IdentityReference reference = claim.Resource as IdentityReference;
- if (null != reference) {
- return reference.Value;
- }
-
- ICspAsymmetricAlgorithm rsa = claim.Resource as ICspAsymmetricAlgorithm;
- if (null != rsa) {
- using (SHA256 sha = SHA256.Create()) {
- return Convert.ToBase64String(sha.ComputeHash(rsa.ExportCspBlob(false)));
- }
- }
-
- MailAddress mail = claim.Resource as MailAddress;
- if (null != mail) {
- return mail.ToString();
- }
-
- byte[] bufferValue = claim.Resource as byte[];
- if (null != bufferValue) {
- return Convert.ToBase64String(bufferValue);
- }
-
- return claim.Resource.ToString();
- }
-
- /// <summary>
- /// Generates a UniqueID based off the Issuer's key
- /// </summary>
- /// <param name="authzContext">the Authorization Context</param>
- /// <returns>the hash of the internal key of the issuer</returns>
- internal static string GetIssuerPubKeyHash(AuthorizationContext authzContext) {
- foreach (ClaimSet cs in authzContext.ClaimSets) {
- Claim currentIssuerClaim = GetUniqueRsaClaim(cs.Issuer);
-
- if (currentIssuerClaim != null) {
- RSA rsa = currentIssuerClaim.Resource as RSA;
- if (null == rsa) {
- return null;
- }
-
- return ComputeCombinedId(rsa, string.Empty);
- }
- }
-
- return null;
- }
-
- /// <summary>
- /// Generates a UniqueID based off the Issuer's key and the PPID.
- /// </summary>
- /// <param name="authzContext">The Authorization Context</param>
- /// <returns>A unique ID for this user at this web site.</returns>
- internal static string GetUniqueName(AuthorizationContext authzContext) {
- Requires.NotNull(authzContext, "authzContext");
-
- Claim uniqueIssuerClaim = null;
- Claim uniqueUserClaim = null;
-
- foreach (ClaimSet cs in authzContext.ClaimSets) {
- Claim currentIssuerClaim = GetUniqueRsaClaim(cs.Issuer);
-
- foreach (Claim c in cs.FindClaims(ClaimTypes.PPID, Rights.PossessProperty)) {
- if (null == currentIssuerClaim) {
- // Found a claim in a ClaimSet with no RSA issuer.
- return null;
- }
-
- if (null == uniqueUserClaim) {
- uniqueUserClaim = c;
- uniqueIssuerClaim = currentIssuerClaim;
- } else if (!uniqueIssuerClaim.Equals(currentIssuerClaim)) {
- // Found two of the desired claims with different
- // issuers. No unique name.
- return null;
- } else if (!uniqueUserClaim.Equals(c)) {
- // Found two of the desired claims with different
- // values. No unique name.
- return null;
- }
- }
- }
-
- // No claim of the desired type was found
- if (null == uniqueUserClaim) {
- return null;
- }
-
- // Unexpected resource type
- string claimValue = uniqueUserClaim.Resource as string;
- if (null == claimValue) {
- return null;
- }
-
- // Unexpected resource type for RSA
- RSA rsa = uniqueIssuerClaim.Resource as RSA;
- if (null == rsa) {
- return null;
- }
-
- return ComputeCombinedId(rsa, claimValue);
- }
-
- /// <summary>
- /// Generates the Site Specific ID to match the one in the Identity Selector.
- /// </summary>
- /// <value>The ID displayed by the Identity Selector.</value>
- /// <param name="ppid">The personal private identifier.</param>
- /// <returns>A string containing the XXX-XXXX-XXX cosmetic value.</returns>
- [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive.")]
- internal static string CalculateSiteSpecificID(string ppid) {
- Requires.NotNull(ppid, "ppid");
-
- int callSignChars = 10;
- char[] charMap = "QL23456789ABCDEFGHJKMNPRSTUVWXYZ".ToCharArray();
- int charMapLength = charMap.Length;
-
- byte[] raw = Convert.FromBase64String(ppid);
- using (HashAlgorithm hasher = SHA1.Create()) {
- raw = hasher.ComputeHash(raw);
- }
-
- StringBuilder callSign = new StringBuilder();
-
- for (int i = 0; i < callSignChars; i++) {
- // after char 3 and char 7, place a dash
- if (i == 3 || i == 7) {
- callSign.Append('-');
- }
- callSign.Append(charMap[raw[i] % charMapLength]);
- }
- return callSign.ToString();
- }
-
- /// <summary>
- /// Gets the Unique RSA Claim from the SAML token.
- /// </summary>
- /// <param name="cs">the claimset which contains the claim</param>
- /// <returns>a RSA claim</returns>
- private static Claim GetUniqueRsaClaim(ClaimSet cs) {
- Requires.NotNull(cs, "cs");
-
- Claim rsa = null;
-
- foreach (Claim c in cs.FindClaims(ClaimTypes.Rsa, Rights.PossessProperty)) {
- if (null == rsa) {
- rsa = c;
- } else if (!rsa.Equals(c)) {
- // Found two non-equal RSA claims
- return null;
- }
- }
- return rsa;
- }
-
- /// <summary>
- /// Does the actual calculation of a combined ID from a value and an RSA key.
- /// </summary>
- /// <param name="issuerKey">The key of the issuer of the token</param>
- /// <param name="claimValue">the claim value to hash with.</param>
- /// <returns>A base64 representation of the combined ID.</returns>
- [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive.")]
- private static string ComputeCombinedId(RSA issuerKey, string claimValue) {
- Requires.NotNull(issuerKey, "issuerKey");
- Requires.NotNull(claimValue, "claimValue");
-
- int nameLength = Encoding.UTF8.GetByteCount(claimValue);
- RSAParameters rsaParams = issuerKey.ExportParameters(false);
- byte[] shaInput;
- byte[] shaOutput;
-
- int i = 0;
- shaInput = new byte[rsaParams.Modulus.Length + rsaParams.Exponent.Length + nameLength];
- rsaParams.Modulus.CopyTo(shaInput, i);
- i += rsaParams.Modulus.Length;
- rsaParams.Exponent.CopyTo(shaInput, i);
- i += rsaParams.Exponent.Length;
- i += Encoding.UTF8.GetBytes(claimValue, 0, claimValue.Length, shaInput, i);
-
- using (SHA256 sha = SHA256.Create()) {
- shaOutput = sha.ComputeHash(shaInput);
- }
-
- return Convert.ToBase64String(shaOutput);
- }
- }
-}
diff --git a/src/DotNetOpenAuth.InfoCard/InfoCard/WellKnownClaimTypes.cs b/src/DotNetOpenAuth.InfoCard/InfoCard/WellKnownClaimTypes.cs
deleted file mode 100644
index 7a00d4d..0000000
--- a/src/DotNetOpenAuth.InfoCard/InfoCard/WellKnownClaimTypes.cs
+++ /dev/null
@@ -1,269 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="WellKnownClaimTypes.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.InfoCard {
- using System.Diagnostics.CodeAnalysis;
-
- /// <summary>
- /// Well known claims that may be included in an Information Card.
- /// </summary>
- public class WellKnownClaimTypes {
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/anonymous" claim.
- /// </summary>
- public const string Anonymous = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/anonymous";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authentication" claim.
- /// </summary>
- public const string Authentication = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authentication";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authorizationdecision" claim.
- /// </summary>
- public const string AuthorizationDecision = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authorizationdecision";
-
- /// <summary>
- /// The date of birth of a subject in a form allowed by the xs:date data type.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth</value>
- public const string DateOfBirth = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid" claim.
- /// </summary>
- public const string DenyOnlySid = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dns" claim.
- /// </summary>
- public const string Dns = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dns";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/hash" claim.
- /// </summary>
- public const string Hash = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/hash";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" claim.
- /// </summary>
- public const string NameIdentifier = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";
-
- /// <summary>
- /// A private personal identifier (PPID) that identifies the subject to a relying party.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier</value>
- /// <remarks>
- /// The word private is used in the sense that the subject identifier is
- /// specific to a given relying party and hence private to that relying party.
- /// A subject's PPID at one relying party cannot be correlated with the subject's
- /// PPID at another relying party.
- /// </remarks>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ppid", Justification = "By design")]
- public const string Ppid = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/rsa" claim.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rsa", Justification = "By design")]
- public const string Rsa = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/rsa";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid" claim.
- /// </summary>
- public const string Sid = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/spn" claim.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Spn", Justification = "By design")]
- public const string Spn = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/spn";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system" claim.
- /// </summary>
- public const string System = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint" claim.
- /// </summary>
- public const string Thumbprint = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" claim.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Upn", Justification = "By design")]
- public const string Upn = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/uri" claim.
- /// </summary>
- public const string Uri = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/uri";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/x500distinguishedname" claim.
- /// </summary>
- public const string X500DistinguishedName = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/x500distinguishedname";
-
- /// <summary>
- /// Prevents a default instance of the <see cref="WellKnownClaimTypes"/> class from being created.
- /// </summary>
- private WellKnownClaimTypes() {
- }
-
- /// <summary>
- /// Inherent attributes about a personality such as gender and bio.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Required for desired autocompletion.")]
- public static class Person {
- /// <summary>
- /// Gender of a subject.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender</value>
- /// <remarks>
- /// The value of the claim can have any of these exact string values
- /// 0 (unspecified) or
- /// 1 (Male) or
- /// 2 (Female). Using these values allows them to be language neutral.
- /// </remarks>
- public const string Gender = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender";
- }
-
- /// <summary>
- /// Various ways to contact a person.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Required for desired autocompletion.")]
- public static class Contact {
- /// <summary>
- /// Preferred address for the To: field of email to be sent to the subject.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress</value>
- /// <remarks>
- /// (mail in inetOrgPerson) Usually of the form @. According to inetOrgPerson using RFC 1274: This attribute type specifies an electronic mailbox attribute following the syntax specified in RFC 822.
- /// </remarks>
- public const string Email = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress";
-
- /// <summary>
- /// Various types of phone numbers.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Required for desired autocompletion.")]
- public static class Phone {
- /// <summary>
- /// Primary or home telephone number of a subject.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/homephone</value>
- /// <remarks>
- /// According to inetOrgPerson using RFC 1274:
- /// This attribute type specifies
- /// a home telephone number associated with a person. Attribute values
- /// should follow the agreed format for international telephone numbers,
- /// e.g. +44 71 123 4567.
- /// </remarks>
- public const string HomePhone = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/homephone";
-
- /// <summary>
- /// Mobile telephone number of a subject.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone</value>
- /// <remarks>
- /// (mobile in inetOrgPerson) According to inetOrgPerson using RFC 1274: This attribute type specifies a mobile telephone number associated with a person. Attribute values should follow the agreed format for international telephone numbers, e.g. +44 71 123 4567.
- /// </remarks>
- public const string MobilePhone = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone" claim.
- /// </summary>
- public const string OtherPhone = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone";
- }
-
- /// <summary>
- /// The many fields that make up an address.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Required for desired autocompletion.")]
- public static class Address {
- /// <summary>
- /// Street address component of a subject's address information.
- /// According to RFC 2256:
- /// This attribute contains the physical address of the object to which
- /// the entry corresponds, such as an address for package delivery.
- /// Its content is arbitrary, but typically given as a PO Box number or
- /// apartment/house number followed by a street name, e.g. 303 Mulberry St.
- /// (street in RFC 2256)
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress</value>
- public const string StreetAddress = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress";
-
- /// <summary>
- /// Locality component of a subject's address information.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality</value>
- /// <remarks>
- /// According to RFC 2256: This attribute contains the name of a locality, such as a city, county or other geographic region. e.g. Redmond.
- /// </remarks>
- public const string City = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality";
-
- /// <summary>
- /// Abbreviation for state or province name of a subject's address information.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince</value>
- /// <remarks>
- /// According to RFC 2256: This attribute contains the full name of a state or province. The values should be coordinated on a national level and if well-known shortcuts exist - like the two-letter state abbreviations in the US these abbreviations are preferred over longer full names. e.g. WA.
- /// </remarks>
- public const string StateOrProvince = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince";
-
- /// <summary>
- /// The "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode" claim.
- /// </summary>
- public const string PostalCode = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode";
-
- /// <summary>
- /// Country of a subject.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country</value>
- /// <remarks>
- /// (c in RFC 2256) According to RFC 2256: This attribute contains a two-letter ISO 3166 country code.
- /// </remarks>
- public const string Country = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country";
- }
-
- /// <summary>
- /// The names a person goes by.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Required for desired autocompletion.")]
- public static class Name {
- /// <summary>
- /// Preferred name or first name of a subject. According to RFC 2256: This attribute is used to hold the part of a persons name which is not their surname nor middle name.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname</value>
- /// <remarks>
- /// (givenName in RFC 2256)
- /// </remarks>
- public const string GivenName = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname";
-
- /// <summary>
- /// Surname or family name of a subject.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname</value>
- /// <remarks>
- /// According to RFC 2256: This is the X.500 surname attribute which contains the family name of a person.
- /// </remarks>
- public const string Surname = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname";
- }
-
- /// <summary>
- /// Various web addresses connected with this personality.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces", Justification = "By design"), SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Required for desired autocompletion.")]
- public static class Web {
- /// <summary>
- /// The Web page of a subject expressed as a URL.
- /// </summary>
- /// <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage</value>
- public const string Homepage = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage";
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/DotNetOpenAuth.InfoCard/InfoCard/WellKnownIssuers.cs b/src/DotNetOpenAuth.InfoCard/InfoCard/WellKnownIssuers.cs
deleted file mode 100644
index 103bac4..0000000
--- a/src/DotNetOpenAuth.InfoCard/InfoCard/WellKnownIssuers.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="WellKnownIssuers.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.InfoCard {
- /// <summary>
- /// Common InfoCard issuers.
- /// </summary>
- public sealed class WellKnownIssuers {
- /// <summary>
- /// The Issuer URI to use for self-issued cards.
- /// </summary>
- public const string SelfIssued = "http://schemas.xmlsoap.org/ws/2005/05/identity/issuer/self";
-
- /// <summary>
- /// Prevents a default instance of the <see cref="WellKnownIssuers"/> class from being created.
- /// </summary>
- private WellKnownIssuers() {
- }
- }
-}