You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			337 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			337 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------
 | |
| // Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| //------------------------------------------------------------
 | |
| 
 | |
| namespace System.IdentityModel.Tokens
 | |
| {
 | |
|     using System;
 | |
|     using System.Collections.Generic;
 | |
|     using System.IdentityModel.Selectors;
 | |
|     using System.Security.Cryptography;
 | |
|     using System.Security.Cryptography.X509Certificates;
 | |
|     using System.ServiceModel.Security;
 | |
|     using System.Xml;
 | |
|     using KeyIdentifierEntry = System.IdentityModel.Selectors.SecurityTokenSerializer.KeyIdentifierEntry;
 | |
| 
 | |
|     class XmlDsigSep2000 : SecurityTokenSerializer.SerializerEntries
 | |
|     {
 | |
|         KeyInfoSerializer securityTokenSerializer;
 | |
| 
 | |
|         public XmlDsigSep2000( KeyInfoSerializer securityTokenSerializer )
 | |
|         {
 | |
|             this.securityTokenSerializer = securityTokenSerializer;
 | |
|         }
 | |
| 
 | |
|         public override void PopulateKeyIdentifierEntries( IList<KeyIdentifierEntry> keyIdentifierEntries )
 | |
|         {
 | |
|             keyIdentifierEntries.Add( new KeyInfoEntry( this.securityTokenSerializer ) );
 | |
|         }
 | |
| 
 | |
|         public override void PopulateKeyIdentifierClauseEntries( IList<SecurityTokenSerializer.KeyIdentifierClauseEntry> keyIdentifierClauseEntries )
 | |
|         {
 | |
|             keyIdentifierClauseEntries.Add( new KeyNameClauseEntry() );
 | |
|             keyIdentifierClauseEntries.Add( new KeyValueClauseEntry() );
 | |
|             keyIdentifierClauseEntries.Add( new X509CertificateClauseEntry() );
 | |
|         }
 | |
| 
 | |
|         internal class KeyInfoEntry : KeyIdentifierEntry
 | |
|         {
 | |
|             KeyInfoSerializer securityTokenSerializer;
 | |
| 
 | |
|             public KeyInfoEntry( KeyInfoSerializer securityTokenSerializer )
 | |
|             {
 | |
|                 this.securityTokenSerializer = securityTokenSerializer;
 | |
|             }
 | |
| 
 | |
|             protected override XmlDictionaryString LocalName
 | |
|             {
 | |
|                 get
 | |
|                 {
 | |
|                     return XD.XmlSignatureDictionary.KeyInfo;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             protected override XmlDictionaryString NamespaceUri
 | |
|             {
 | |
|                 get
 | |
|                 {
 | |
|                     return XD.XmlSignatureDictionary.Namespace;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             public override SecurityKeyIdentifier ReadKeyIdentifierCore( XmlDictionaryReader reader )
 | |
|             {
 | |
|                 reader.ReadStartElement( LocalName, NamespaceUri );
 | |
|                 SecurityKeyIdentifier keyIdentifier = new SecurityKeyIdentifier();
 | |
|                 while ( reader.IsStartElement() )
 | |
|                 {
 | |
|                     SecurityKeyIdentifierClause clause = this.securityTokenSerializer.ReadKeyIdentifierClause( reader );
 | |
|                     if ( clause == null )
 | |
|                     {
 | |
|                         reader.Skip();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         keyIdentifier.Add( clause );
 | |
|                     }
 | |
|                 }
 | |
|                 if ( keyIdentifier.Count == 0 )
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException( SR.GetString( SR.ErrorDeserializingKeyIdentifierClause ) ) );
 | |
|                 }
 | |
|                 reader.ReadEndElement();
 | |
|                 return keyIdentifier;
 | |
|             }
 | |
| 
 | |
|             public override bool SupportsCore( SecurityKeyIdentifier keyIdentifier )
 | |
|             {
 | |
|                 return true;
 | |
|             }
 | |
| 
 | |
|             public override void WriteKeyIdentifierCore( XmlDictionaryWriter writer, SecurityKeyIdentifier keyIdentifier )
 | |
|             {
 | |
|                 writer.WriteStartElement( XD.XmlSignatureDictionary.Prefix.Value, LocalName, NamespaceUri );
 | |
|                 bool clauseWritten = false;
 | |
|                 foreach ( SecurityKeyIdentifierClause clause in keyIdentifier )
 | |
|                 {
 | |
|                     this.securityTokenSerializer.InnerSecurityTokenSerializer.WriteKeyIdentifierClause( writer, clause );
 | |
|                     clauseWritten = true;
 | |
|                 }
 | |
|                 writer.WriteEndElement(); // KeyInfo
 | |
|                 if ( !clauseWritten )
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityMessageSerializationException( SR.GetString( SR.NoKeyInfoClausesToWrite ) ) );
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // <ds:KeyName>name</ds:KeyName>
 | |
|         internal class KeyNameClauseEntry : SecurityTokenSerializer.KeyIdentifierClauseEntry
 | |
|         {
 | |
|             protected override XmlDictionaryString LocalName
 | |
|             {
 | |
|                 get
 | |
|                 {
 | |
|                     return XD.XmlSignatureDictionary.KeyName;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             protected override XmlDictionaryString NamespaceUri
 | |
|             {
 | |
|                 get
 | |
|                 {
 | |
|                     return XD.XmlSignatureDictionary.Namespace;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             public override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore( XmlDictionaryReader reader )
 | |
|             {
 | |
|                 reader.ReadStartElement( XD.XmlSignatureDictionary.KeyName, NamespaceUri );
 | |
|                 string name = reader.ReadString();
 | |
|                 reader.ReadEndElement();
 | |
| 
 | |
|                 return new KeyNameIdentifierClause( name );
 | |
|             }
 | |
| 
 | |
|             public override bool SupportsCore( SecurityKeyIdentifierClause keyIdentifierClause )
 | |
|             {
 | |
|                 return keyIdentifierClause is KeyNameIdentifierClause;
 | |
|             }
 | |
| 
 | |
|             public override void WriteKeyIdentifierClauseCore( XmlDictionaryWriter writer, SecurityKeyIdentifierClause keyIdentifierClause )
 | |
|             {
 | |
|                 KeyNameIdentifierClause nameClause = keyIdentifierClause as KeyNameIdentifierClause;
 | |
| 
 | |
|                 writer.WriteElementString( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.KeyName, NamespaceUri, nameClause.KeyName );
 | |
|             }
 | |
|         }
 | |
|         // so far, we only support one type of KeyValue - RSAKeyValue
 | |
|         //   <ds:KeyValue>
 | |
|         //     <ds:RSAKeyValue>
 | |
|         //       <ds:Modulus>xA7SEU+...</ds:Modulus>
 | |
|         //         <ds:Exponent>AQAB</Exponent>
 | |
|         //     </ds:RSAKeyValue>
 | |
|         //   </ds:KeyValue>
 | |
|         internal class KeyValueClauseEntry : SecurityTokenSerializer.KeyIdentifierClauseEntry
 | |
|         {
 | |
|             protected override XmlDictionaryString LocalName
 | |
|             {
 | |
|                 get
 | |
|                 {
 | |
|                     return XD.XmlSignatureDictionary.KeyValue;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             protected override XmlDictionaryString NamespaceUri
 | |
|             {
 | |
|                 get
 | |
|                 {
 | |
|                     return XD.XmlSignatureDictionary.Namespace;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
| 
 | |
|             public override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore( XmlDictionaryReader reader )
 | |
|             {
 | |
|                 reader.ReadStartElement( XD.XmlSignatureDictionary.KeyValue, NamespaceUri );
 | |
|                 reader.ReadStartElement( XD.XmlSignatureDictionary.RsaKeyValue, NamespaceUri );
 | |
|                 reader.ReadStartElement( XD.XmlSignatureDictionary.Modulus, NamespaceUri );
 | |
| 
 | |
|                 byte[] modulus = Convert.FromBase64String( reader.ReadString() );
 | |
| 
 | |
|                 reader.ReadEndElement();
 | |
|                 reader.ReadStartElement( XD.XmlSignatureDictionary.Exponent, NamespaceUri );
 | |
|                 byte[] exponent = Convert.FromBase64String( reader.ReadString() );
 | |
|                 reader.ReadEndElement();
 | |
|                 reader.ReadEndElement();
 | |
|                 reader.ReadEndElement();
 | |
| 
 | |
|                 RSA rsa = new RSACryptoServiceProvider();
 | |
|                 RSAParameters rsaParameters = new RSAParameters();
 | |
|                 rsaParameters.Modulus = modulus;
 | |
|                 rsaParameters.Exponent = exponent;
 | |
|                 rsa.ImportParameters( rsaParameters );
 | |
| 
 | |
|                 return new RsaKeyIdentifierClause( rsa );
 | |
|             }
 | |
| 
 | |
|             public override bool SupportsCore( SecurityKeyIdentifierClause keyIdentifierClause )
 | |
|             {
 | |
|                 return keyIdentifierClause is RsaKeyIdentifierClause;
 | |
|             }
 | |
| 
 | |
|             public override void WriteKeyIdentifierClauseCore( XmlDictionaryWriter writer, SecurityKeyIdentifierClause keyIdentifierClause )
 | |
|             {
 | |
|                 RsaKeyIdentifierClause rsaClause = keyIdentifierClause as RsaKeyIdentifierClause;
 | |
| 
 | |
|                 writer.WriteStartElement( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.KeyValue, NamespaceUri );
 | |
|                 writer.WriteStartElement( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.RsaKeyValue, NamespaceUri );
 | |
|                 writer.WriteStartElement( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.Modulus, NamespaceUri );
 | |
|                 rsaClause.WriteModulusAsBase64( writer );
 | |
|                 writer.WriteEndElement();
 | |
|                 writer.WriteStartElement( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.Exponent, NamespaceUri );
 | |
|                 rsaClause.WriteExponentAsBase64( writer );
 | |
|                 writer.WriteEndElement();
 | |
|                 writer.WriteEndElement();
 | |
|                 writer.WriteEndElement();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // so far, we only support two types of X509Data directly under KeyInfo  - X509Certificate and X509SKI
 | |
|         //   <ds:X509Data>
 | |
|         //     <ds:X509Certificate>...</ds:X509Certificate>
 | |
|         //      or
 | |
|         //     <X509SKI>... </X509SKI>
 | |
|         //   </ds:X509Data>
 | |
|         // only support 1 certificate right now
 | |
|         internal class X509CertificateClauseEntry : SecurityTokenSerializer.KeyIdentifierClauseEntry
 | |
|         {
 | |
|             protected override XmlDictionaryString LocalName
 | |
|             {
 | |
|                 get
 | |
|                 {
 | |
|                     return XD.XmlSignatureDictionary.X509Data;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             protected override XmlDictionaryString NamespaceUri
 | |
|             {
 | |
|                 get
 | |
|                 {
 | |
|                     return XD.XmlSignatureDictionary.Namespace;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             public override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore( XmlDictionaryReader reader )
 | |
|             {
 | |
|                 SecurityKeyIdentifierClause ski = null;
 | |
|                 reader.ReadStartElement( XD.XmlSignatureDictionary.X509Data, NamespaceUri );
 | |
|                 while ( reader.IsStartElement() )
 | |
|                 {
 | |
|                     if ( ski == null && reader.IsStartElement( XD.XmlSignatureDictionary.X509Certificate, NamespaceUri ) )
 | |
|                     {
 | |
|                         X509Certificate2 certificate = null;
 | |
|                         if ( !SecurityUtils.TryCreateX509CertificateFromRawData( reader.ReadElementContentAsBase64(), out certificate ) )
 | |
|                         {
 | |
|                             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityMessageSerializationException( SR.GetString( SR.InvalidX509RawData ) ) );
 | |
|                         }
 | |
|                         ski = new X509RawDataKeyIdentifierClause( certificate );
 | |
|                     }
 | |
|                     else if ( ski == null && reader.IsStartElement( XmlSignatureStrings.X509Ski, NamespaceUri.ToString() ) )
 | |
|                     {
 | |
|                         ski = new X509SubjectKeyIdentifierClause( reader.ReadElementContentAsBase64() );
 | |
|                     }
 | |
|                     else if ( ( ski == null ) && reader.IsStartElement( XD.XmlSignatureDictionary.X509IssuerSerial, XD.XmlSignatureDictionary.Namespace ) )
 | |
|                     {
 | |
|                         reader.ReadStartElement( XD.XmlSignatureDictionary.X509IssuerSerial, XD.XmlSignatureDictionary.Namespace );
 | |
|                         reader.ReadStartElement( XD.XmlSignatureDictionary.X509IssuerName, XD.XmlSignatureDictionary.Namespace );
 | |
|                         string issuerName = reader.ReadContentAsString();
 | |
|                         reader.ReadEndElement();
 | |
|                         reader.ReadStartElement( XD.XmlSignatureDictionary.X509SerialNumber, XD.XmlSignatureDictionary.Namespace );
 | |
|                         string serialNumber = reader.ReadContentAsString();
 | |
|                         reader.ReadEndElement();
 | |
|                         reader.ReadEndElement();
 | |
| 
 | |
|                         ski = new X509IssuerSerialKeyIdentifierClause( issuerName, serialNumber );
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         reader.Skip();
 | |
|                     }
 | |
|                 }
 | |
|                 reader.ReadEndElement();
 | |
|                 return ski;
 | |
|             }
 | |
| 
 | |
|             public override bool SupportsCore( SecurityKeyIdentifierClause keyIdentifierClause )
 | |
|             {
 | |
|                 return (keyIdentifierClause is X509RawDataKeyIdentifierClause);
 | |
|                 // This method should not write X509IssuerSerialKeyIdentifierClause or X509SubjectKeyIdentifierClause as that should be written by the WSSecurityXXX classes with SecurityTokenReference tag. 
 | |
|                 // The XmlDsig entries are written by the X509SecurityTokenHandler.
 | |
|             }
 | |
| 
 | |
|             public override void WriteKeyIdentifierClauseCore( XmlDictionaryWriter writer, SecurityKeyIdentifierClause keyIdentifierClause )
 | |
|             {
 | |
|                 X509RawDataKeyIdentifierClause x509Clause = keyIdentifierClause as X509RawDataKeyIdentifierClause;
 | |
| 
 | |
|                 if ( x509Clause != null )
 | |
|                 {
 | |
|                     writer.WriteStartElement( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509Data, NamespaceUri );
 | |
| 
 | |
|                     writer.WriteStartElement( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509Certificate, NamespaceUri );
 | |
|                     byte[] certBytes = x509Clause.GetX509RawData();
 | |
|                     writer.WriteBase64( certBytes, 0, certBytes.Length );
 | |
|                     writer.WriteEndElement();
 | |
| 
 | |
|                     writer.WriteEndElement();
 | |
|                 }
 | |
| 
 | |
|                 X509IssuerSerialKeyIdentifierClause issuerSerialClause = keyIdentifierClause as X509IssuerSerialKeyIdentifierClause;
 | |
|                 if ( issuerSerialClause != null )
 | |
|                 {                    
 | |
|                     writer.WriteStartElement( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509Data, XD.XmlSignatureDictionary.Namespace );
 | |
|                     writer.WriteStartElement( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509IssuerSerial, XD.XmlSignatureDictionary.Namespace );
 | |
|                     writer.WriteElementString( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509IssuerName, XD.XmlSignatureDictionary.Namespace, issuerSerialClause.IssuerName );
 | |
|                     writer.WriteElementString( XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509SerialNumber, XD.XmlSignatureDictionary.Namespace, issuerSerialClause.IssuerSerialNumber );
 | |
|                     writer.WriteEndElement();
 | |
|                     writer.WriteEndElement();
 | |
|                     return;
 | |
|                 }
 | |
| 
 | |
|                 X509SubjectKeyIdentifierClause skiClause = keyIdentifierClause as X509SubjectKeyIdentifierClause;
 | |
|                 if ( skiClause != null )
 | |
|                 {
 | |
|                     writer.WriteStartElement( XmlSignatureConstants.Prefix, XmlSignatureConstants.Elements.X509Data, XmlSignatureConstants.Namespace );
 | |
|                     writer.WriteStartElement( XmlSignatureConstants.Prefix, XmlSignatureConstants.Elements.X509SKI, XmlSignatureConstants.Namespace );
 | |
|                     byte[] ski = skiClause.GetX509SubjectKeyIdentifier();
 | |
|                     writer.WriteBase64( ski, 0, ski.Length );
 | |
|                     writer.WriteEndElement();
 | |
|                     writer.WriteEndElement();
 | |
|                     return;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 |