Просмотр исходного кода

2003-12-07 Sebastien Pouliot <[email protected]>

	* ContentInfo.cs: Modified default Oid not to include description.
	Added basic support for static GetContentType.
	* EnvelopedPkcs7.cs: New. Partial implementation of PKCS#7 envelopes
	(encrypted data).
	* KeyAgreeRecipientInfo.cs: New. Stub for key agreement informations.
	Note that key agreement algorithms (DH) are absent from the framework.
	* KeyTransRecipientInfo.cs: New. Implementation for key transport
	informations.
	* Pkcs7Recipient.cs: New. Implementation of "recipients" - how it
	links to a X.509 certificate (issuer and serial key or subject key
	info).
	* Pkcs7RecipientCollection.cs: New. Collection of Pkcs7Recipient.
	* Pkcs7RecipientEnumerator.cs: New. Enumerator for Pkcs7Recipient.
	* Pkcs7AttributeCollection.cs: New. Collection of Pkcs9Attributes.
	* Pkcs7AttributeEnumerator.cs: New. Enumerator for Pkcs9Attributes.
	* PublicKeyInfo.cs: New. Handle public key informations.
	* RecipientInfoCollection.cs: New. Collection of RecipientInfo (and
	inherited classes).
	* RecipientInfoEnumerator.cs: New. Enumerator for RecipientInfo (and
	inherited classes).
	* SignedPkcs7.cs: New. Partial implementation of PKCS#7 signed
	structures.
	* SignerInfo.cs: New. Information (certificate and attributes) about
	the signer. Actual signature/verification stuff is missing.
	* SignerInfoCollection.cs: New. Collection of SignerInfo.
	* SignerInfoEnumarator.cs: New. Enumerator for SignerInfo.
	* SubjectIdentifier.cs: New. Contains the type of identifier linking
	to a subject.
	* SubjectIdentifierOrKey.cs: New. Contains the subject's public key or
	an information linking to a subject public key.

svn path=/trunk/mcs/; revision=20843
Sebastien Pouliot 22 лет назад
Родитель
Сommit
a7dc35c1f9
19 измененных файлов с 1411 добавлено и 5 удалено
  1. 33 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/ChangeLog
  2. 11 5
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/ContentInfo.cs
  3. 226 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/EnvelopedPkcs7.cs
  4. 52 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyAgreeRecipientInfo.cs
  5. 52 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyTransRecipientInfo.cs
  6. 49 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7Recipient.cs
  7. 94 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientCollection.cs
  8. 52 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientEnumerator.cs
  9. 78 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeCollection.cs
  10. 52 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeEnumerator.cs
  11. 43 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/PublicKeyInfo.cs
  12. 74 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoCollection.cs
  13. 52 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoEnumerator.cs
  14. 254 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignedPkcs7.cs
  15. 88 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfo.cs
  16. 71 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoCollection.cs
  17. 52 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoEnumerator.cs
  18. 39 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifier.cs
  19. 39 0
      mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifierOrKey.cs

+ 33 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/ChangeLog

@@ -1,3 +1,36 @@
+2003-12-07  Sebastien Pouliot  <[email protected]>
+
+	* ContentInfo.cs: Modified default Oid not to include description. 
+	Added basic support for static GetContentType.
+	* EnvelopedPkcs7.cs: New. Partial implementation of PKCS#7 envelopes
+	(encrypted data).
+	* KeyAgreeRecipientInfo.cs: New. Stub for key agreement informations.
+	Note that key agreement algorithms (DH) are absent from the framework.
+	* KeyTransRecipientInfo.cs: New. Implementation for key transport
+	informations. 
+	* Pkcs7Recipient.cs: New. Implementation of "recipients" - how it 
+	links to a X.509 certificate (issuer and serial key or subject key 
+	info).
+	* Pkcs7RecipientCollection.cs: New. Collection of Pkcs7Recipient.
+	* Pkcs7RecipientEnumerator.cs: New. Enumerator for Pkcs7Recipient.
+	* Pkcs7AttributeCollection.cs: New. Collection of Pkcs9Attributes.
+	* Pkcs7AttributeEnumerator.cs: New. Enumerator for Pkcs9Attributes.
+	* PublicKeyInfo.cs: New. Handle public key informations.
+	* RecipientInfoCollection.cs: New. Collection of RecipientInfo (and
+	inherited classes).
+	* RecipientInfoEnumerator.cs: New. Enumerator for RecipientInfo (and
+	inherited classes).
+	* SignedPkcs7.cs: New. Partial implementation of PKCS#7 signed
+	structures.
+	* SignerInfo.cs: New. Information (certificate and attributes) about 
+	the signer. Actual signature/verification stuff is missing.
+	* SignerInfoCollection.cs: New. Collection of SignerInfo.
+	* SignerInfoEnumarator.cs: New. Enumerator for SignerInfo.
+	* SubjectIdentifier.cs: New. Contains the type of identifier linking
+	to a subject.
+	* SubjectIdentifierOrKey.cs: New. Contains the subject's public key or
+	an information linking to a subject public key.
+
 2003-11-08  Sebastien Pouliot  <[email protected]>
 
 	* ContentInfo.cs: New. Class to encapsulate PKCS7 ContentInfo. Static 

+ 11 - 5
mcs/class/System.Security/System.Security.Cryptography.Pkcs/ContentInfo.cs

@@ -30,7 +30,7 @@ namespace System.Security.Cryptography.Pkcs {
 		// constructors
 
 		public ContentInfo (byte[] content) 
-			: this (new Oid ("1.2.840.113549.1.7.1", "PKCS 7 Data"), content) {} 
+			: this (new Oid ("1.2.840.113549.1.7.1"), content) {} 
 
 		public ContentInfo (Oid oid, byte[] content) 
 		{
@@ -55,19 +55,25 @@ namespace System.Security.Cryptography.Pkcs {
 
 		// static methods
 
-		[MonoTODO]
+		[MonoTODO("Incomplete OID support")]
 		public static Oid GetContentType (byte[] encodedMessage)
 		{
 // FIXME: compatibility with fx 1.2.3400.0
 			if (encodedMessage == null)
 				throw new NullReferenceException ();
 //				throw new ArgumentNullException ("algorithm");
-
 			try {
-				return null;
+				PKCS7.ContentInfo ci = new PKCS7.ContentInfo (encodedMessage);
+				switch (ci.ContentType) {
+					// TODO - there are probably more - need testing
+					case PKCS7.signedData:
+						return new Oid (ci.ContentType);
+					default:
+						throw new CryptographicException ("Bad ASN1 - invalid OID");
+				}
 			}
 			catch (Exception e) {
-				throw new CryptographicException ("Bad ASN1", e);
+				throw new CryptographicException ("Bad ASN1 - invalid structure", e);
 			}
 		}
 	}

+ 226 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/EnvelopedPkcs7.cs

@@ -0,0 +1,226 @@
+//
+// EnvelopedPkcs7.cs - System.Security.Cryptography.Pkcs.EnvelopedPkcs7
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+using System.Security.Cryptography.X509Certificates;
+using System.Security.Cryptography.Xml;
+using System.Text;
+
+using Mono.Security;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	// References
+	// a.	PKCS #7: Cryptographic Message Syntax, Version 1.5, Section 10
+	//	http://www.faqs.org/rfcs/rfc2315.html
+
+	public class EnvelopedPkcs7 {
+
+		private ContentInfo _content;
+		private AlgorithmIdentifier _identifier;
+		private X509CertificateExCollection _certs;
+		private RecipientInfoCollection _recipients;
+		private Pkcs9AttributeCollection _uattribs;
+		private SubjectIdentifierType _idType;
+		private int _version;
+
+		// constructors
+
+		public EnvelopedPkcs7 () 
+		{
+			_certs = new X509CertificateExCollection ();
+			_recipients = new RecipientInfoCollection ();
+			_uattribs = new Pkcs9AttributeCollection ();
+		}
+
+		public EnvelopedPkcs7 (ContentInfo content) : this ()
+		{
+			if (content == null)
+				throw new ArgumentNullException ("content");
+
+			_content = content;
+		}
+
+		public EnvelopedPkcs7 (ContentInfo contentInfo,	AlgorithmIdentifier encryptionAlgorithm)
+			: this (contentInfo) 
+		{
+			if (encryptionAlgorithm == null)
+				throw new ArgumentNullException ("encryptionAlgorithm");
+
+			_identifier = encryptionAlgorithm;
+		}
+
+		public EnvelopedPkcs7 (SubjectIdentifierType recipientIdentifierType, ContentInfo contentInfo) 
+			: this (contentInfo) 
+		{
+			_idType = recipientIdentifierType;
+			_version = ((_idType == SubjectIdentifierType.SubjectKeyIdentifier) ? 2 : 0);
+		}
+
+		public EnvelopedPkcs7 (SubjectIdentifierType recipientIdentifierType, ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm)
+			: this (contentInfo, encryptionAlgorithm) 
+		{
+			_idType = recipientIdentifierType;
+			_version = ((_idType == SubjectIdentifierType.SubjectKeyIdentifier) ? 2 : 0);
+		}
+
+		// properties
+
+		public X509CertificateExCollection Certificates {
+			get { return _certs; }
+		}
+
+		public AlgorithmIdentifier ContentEncryptionAlgorithm {
+			get { 
+				if (_identifier == null)
+					_identifier = new AlgorithmIdentifier ();
+				return _identifier; 
+			}
+		} 
+
+		public ContentInfo ContentInfo {
+			get { 
+				if (_content == null) {
+					Oid oid = new Oid (PKCS7.data);
+					_content = new ContentInfo (oid, new byte [0]);
+				}
+				return _content; 
+			}
+		}
+
+		public RecipientInfoCollection RecipientInfos {
+			get { return _recipients; }
+		}
+
+		public Pkcs9AttributeCollection UnprotectedAttributes { 
+			get { return _uattribs; }
+		}
+
+		public int Version {
+			get { return _version; }
+		}
+
+		// methods
+
+		private X509IssuerSerial GetIssuerSerial (string issuer, byte[] serial) 
+		{
+			X509IssuerSerial xis = new X509IssuerSerial ();
+			xis.IssuerName = issuer;
+			StringBuilder sb = new StringBuilder ();
+			foreach (byte b in serial)
+				sb.Append (b.ToString ("X2"));
+			xis.SerialNumber = sb.ToString ();
+			return xis;
+		}
+
+		[MonoTODO]
+		public void Decode (byte[] encodedMessage)
+		{
+			if (encodedMessage == null)
+				throw new ArgumentNullException ("encodedMessage");
+
+			PKCS7.ContentInfo ci = new PKCS7.ContentInfo (encodedMessage);
+			if (ci.ContentType != PKCS7.envelopedData)
+				throw new Exception ("");
+
+			PKCS7.EnvelopedData ed = new PKCS7.EnvelopedData (ci.Content);
+
+			Oid oid = new Oid (ed.ContentInfo.ContentType);
+			_content = new ContentInfo (oid, new byte [0]); //ed.ContentInfo.Content.Value);
+
+			foreach (PKCS7.RecipientInfo ri in ed.RecipientInfos) {
+				Oid o = new Oid (ri.Oid);
+				AlgorithmIdentifier ai = new AlgorithmIdentifier (o);
+				SubjectIdentifier si = null;
+				if (ri.SubjectKeyIdentifier != null) {
+					si = new SubjectIdentifier (SubjectIdentifierType.SubjectKeyIdentifier, ri.SubjectKeyIdentifier);
+				}
+				else if ((ri.Issuer != null) && (ri.Serial != null)) {
+					X509IssuerSerial xis = GetIssuerSerial (ri.Issuer, ri.Serial);
+					si = new SubjectIdentifier (SubjectIdentifierType.IssuerAndSerialNumber, (object)xis);
+				}
+				
+				KeyTransRecipientInfo _keyTrans = new KeyTransRecipientInfo (ri.Key, ai, si, ri.Version);
+				_recipients.Add (_keyTrans);
+			}
+
+			// TODO - Certificates
+			// TODO - UnprotectedAttributes 
+
+			_version = ed.Version;
+		}
+
+		[MonoTODO]
+		public void Decrypt () 
+		{
+			throw new InvalidOperationException ("not encrypted");
+		}
+
+		[MonoTODO]
+		public void Decrypt (RecipientInfo recipientInfo) 
+		{
+			if (recipientInfo == null)
+				throw new ArgumentNullException ("recipientInfo");
+			Decrypt ();
+		}
+
+		[MonoTODO]
+		public void Decrypt (RecipientInfo recipientInfo, X509CertificateExCollection extraStore)
+		{
+			if (recipientInfo == null)
+				throw new ArgumentNullException ("recipientInfo");
+			if (extraStore == null)
+				throw new ArgumentNullException ("extraStore");
+			Decrypt ();
+		}
+
+		[MonoTODO]
+		public void Decrypt (X509CertificateExCollection extraStore) 
+		{
+			if (extraStore == null)
+				throw new ArgumentNullException ("extraStore");
+			Decrypt ();
+		}
+
+		[MonoTODO]
+		public byte[] Encode ()
+		{
+			throw new InvalidOperationException ("not encrypted");
+		}
+
+		[MonoTODO]
+		public void Encrypt () 
+		{
+			if ((_content.Content == null) || (_content.Content.Length == 0))
+				throw new CryptographicException ("no content to encrypt");
+		}
+
+		[MonoTODO]
+		public void Encrypt (Pkcs7Recipient recipient)
+		{
+			if (recipient == null)
+				throw new ArgumentNullException ("recipient");
+			// TODO
+			Encrypt ();
+		}
+
+		[MonoTODO]
+		public void Encrypt (Pkcs7RecipientCollection recipients)
+		{
+			if (recipients == null)
+				throw new ArgumentNullException ("recipients");
+			// ? foreach on Encrypt Pkcs7Recipient ?
+		}
+	}
+}
+
+#endif

+ 52 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyAgreeRecipientInfo.cs

@@ -0,0 +1,52 @@
+//
+// KeyAgreeRecipientInfo.cs - System.Security.Cryptography.Pkcs.KeyAgreeRecipientInfo
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	[MonoTODO]
+	public sealed class KeyAgreeRecipientInfo : RecipientInfo {
+
+		// only accessible from EnvelopedPkcs7.RecipientInfos
+		internal KeyAgreeRecipientInfo () {}
+
+		public DateTime Date {
+			get { return DateTime.MinValue; }
+		}
+
+		public override byte[] EncryptedKey {
+			get { return null; }
+		}
+
+		public override AlgorithmIdentifier KeyEncryptionAlgorithm {
+			get { return null; }
+		}
+
+		public SubjectIdentifierOrKey OriginatorIdentifierOrKey {
+			get { return null; }
+		}
+
+		public CryptographicAttribute OtherKeyAttribute {
+			get { return null; }
+		}
+
+		public override SubjectIdentifier RecipientIdentifier {
+			get { return null; }
+		}
+
+		public override int Version {
+			get { return 0; }
+		}
+	}
+}
+
+#endif

+ 52 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyTransRecipientInfo.cs

@@ -0,0 +1,52 @@
+//
+// KeyTransRecipientInfo.cs - System.Security.Cryptography.Pkcs.KeyTransRecipientInfo
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public sealed class KeyTransRecipientInfo : RecipientInfo {
+
+		private byte[] _encryptedKey;
+		private AlgorithmIdentifier _keyEncryptionAlgorithm;
+		private SubjectIdentifier _recipientIdentifier;
+		private int _version;
+
+		// only accessible from EnvelopedPkcs7.RecipientInfos
+		internal KeyTransRecipientInfo (byte[] encryptedKey, AlgorithmIdentifier keyEncryptionAlgorithm, SubjectIdentifier recipientIdentifier, int version)
+			: base (RecipientInfoType.KeyTransport)
+		{
+			_encryptedKey = encryptedKey;
+			_keyEncryptionAlgorithm = keyEncryptionAlgorithm;
+			_recipientIdentifier = recipientIdentifier;
+			_version = version;
+		}
+
+		public override byte[] EncryptedKey {
+			get { return _encryptedKey; }
+		}
+
+		public override AlgorithmIdentifier KeyEncryptionAlgorithm {
+			get { return _keyEncryptionAlgorithm; }
+		} 
+
+		public override SubjectIdentifier RecipientIdentifier {
+			get { return _recipientIdentifier; }
+		} 
+
+		public override int Version {
+			get { return _version; }
+		}
+	}
+}
+
+#endif

+ 49 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7Recipient.cs

@@ -0,0 +1,49 @@
+//
+// Pkcs7Recipient.cs - System.Security.Cryptography.Pkcs.Pkcs7Recipient
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class Pkcs7Recipient {
+
+		private SubjectIdentifierType _recipient;
+		private X509CertificateEx _certificate;
+
+		// constructor
+
+		public Pkcs7Recipient (SubjectIdentifierType recipientIdentifierType, X509CertificateEx certificate)
+		{
+			if (certificate == null)
+				throw new ArgumentNullException ("certificate");
+
+			if (recipientIdentifierType == SubjectIdentifierType.Unknown)
+				_recipient = SubjectIdentifierType.IssuerAndSerialNumber;
+			else
+				_recipient = recipientIdentifierType;
+			_certificate = certificate;
+		}
+
+		// properties
+
+		public X509CertificateEx Certificate {
+			get { return _certificate; }
+		}
+
+		public SubjectIdentifierType RecipientIdentifierType {
+			get { return _recipient; }
+		}
+	}
+}
+
+#endif

+ 94 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientCollection.cs

@@ -0,0 +1,94 @@
+//
+// Pkcs7RecipientCollection.cs - System.Security.Cryptography.Pkcs.Pkcs7RecipientCollection
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class Pkcs7RecipientCollection : ICollection, IEnumerable {
+
+		private ArrayList _list;
+
+		// constructors
+
+		public Pkcs7RecipientCollection () 
+		{
+			_list = new ArrayList ();
+		}
+
+		public Pkcs7RecipientCollection (Pkcs7Recipient recipient) : base () 
+		{
+			_list.Add (recipient);
+		}
+
+		public Pkcs7RecipientCollection (SubjectIdentifierType recipientIdentifierType, X509CertificateExCollection certificates) : base () 
+		{
+			foreach (X509CertificateEx x509 in certificates) {
+				Pkcs7Recipient p7r = new Pkcs7Recipient (recipientIdentifierType, x509);
+				_list.Add (p7r);
+			}
+		}
+
+		// properties
+
+		public int Count {
+			get { return _list.Count; }
+		}
+
+		public bool IsSynchronized {
+			get { return _list.IsSynchronized; }
+		}
+
+		public Pkcs7Recipient this [int index] {
+			get { return (Pkcs7Recipient) _list [index]; }
+		}
+
+		public object SyncRoot {
+			get { return _list.SyncRoot; }
+		}
+
+		// methods
+
+		public int Add (Pkcs7Recipient recipient) 
+		{
+			return _list.Add (recipient);
+		}
+
+		public void CopyTo (Array array, int index) 
+		{
+			_list.CopyTo (array, index);
+		}
+
+		public void CopyTo (Pkcs7Recipient[] array, int index) 
+		{
+			_list.CopyTo (array, index);
+		}
+
+		public Pkcs7RecipientEnumerator GetEnumerator () 
+		{
+			return new Pkcs7RecipientEnumerator (_list);
+		}
+
+		IEnumerator IEnumerable.GetEnumerator ()
+		{
+			return new Pkcs7RecipientEnumerator (_list);
+		}
+
+		public void Remove (Pkcs7Recipient recipient) 
+		{
+			_list.Remove (recipient);
+		}
+	}
+}
+
+#endif

+ 52 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientEnumerator.cs

@@ -0,0 +1,52 @@
+//
+// Pkcs7RecipientEnumerator.cs - System.Security.Cryptography.Pkcs.Pkcs7RecipientEnumerator
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class Pkcs7RecipientEnumerator : IEnumerator {
+
+		private IEnumerator enumerator;
+
+		// constructors
+
+		internal Pkcs7RecipientEnumerator (IEnumerable enumerable) 
+		{
+			enumerator = enumerable.GetEnumerator ();
+		}
+
+		// properties
+
+		public Pkcs7Recipient Current {
+			get { return (Pkcs7Recipient) enumerator.Current; }
+		}
+
+		object IEnumerator.Current {
+			get { return enumerator.Current; }
+		}
+
+		// methods
+
+		public bool MoveNext () 
+		{
+			return enumerator.MoveNext ();
+		}
+
+		public void Reset ()
+		{
+			enumerator.Reset ();
+		}
+	}
+}
+
+#endif

+ 78 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeCollection.cs

@@ -0,0 +1,78 @@
+//
+// Pkcs9AttributeCollection.cs - System.Security.Cryptography.Pkcs.Pkcs9AttributeCollection
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class Pkcs9AttributeCollection : ICollection {
+
+		private ArrayList _list;
+
+		public Pkcs9AttributeCollection () 
+		{
+			_list = new ArrayList ();
+		}
+
+		// properties
+
+		public int Count {
+			get { return _list.Count; }
+		}
+
+		public bool IsSynchronized {
+			get { return _list.IsSynchronized; }
+		}
+
+		public Pkcs9Attribute this [int index] {
+			get { return (Pkcs9Attribute) _list [index]; }
+		}
+
+		public object SyncRoot {
+			get { return _list.SyncRoot; }
+		}
+
+		// methods
+
+		public int Add (Pkcs9Attribute attribute)
+		{
+			return _list.Add (attribute);
+		}
+
+		public void CopyTo (Array array, int index)
+		{
+			_list.CopyTo (array, index);
+		}
+
+		public void CopyTo (Pkcs9Attribute[] array, int index)
+		{
+			_list.CopyTo (array, index);
+		}
+
+		public Pkcs9AttributeEnumerator GetEnumerator () 
+		{
+			return new Pkcs9AttributeEnumerator (_list);
+		}
+
+		IEnumerator IEnumerable.GetEnumerator () 
+		{
+			return new Pkcs9AttributeEnumerator (_list);
+		}
+
+		public void Remove (Pkcs9Attribute attribute) 
+		{
+			_list.Remove (attribute);
+		}
+	}
+}
+
+#endif

+ 52 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeEnumerator.cs

@@ -0,0 +1,52 @@
+//
+// Pkcs9AttributeEnumerator.cs - System.Security.Cryptography.Pkcs.Pkcs9AttributeEnumerator
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class Pkcs9AttributeEnumerator : IEnumerator {
+
+		private IEnumerator enumerator;
+
+		// constructors
+
+		internal Pkcs9AttributeEnumerator (IEnumerable enumerable) 
+		{
+			enumerator = enumerable.GetEnumerator ();
+		}
+
+		// properties
+
+		public Pkcs9Attribute Current {
+			get { return (Pkcs9Attribute) enumerator.Current; }
+		}
+
+		object IEnumerator.Current {
+			get { return enumerator.Current; }
+		}
+
+		// methods
+
+		public bool MoveNext () 
+		{
+			return enumerator.MoveNext ();
+		}
+
+		public void Reset ()
+		{
+			enumerator.Reset ();
+		}
+	}
+}
+
+#endif

+ 43 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/PublicKeyInfo.cs

@@ -0,0 +1,43 @@
+//
+// PublicKeyInfo.cs - System.Security.Cryptography.Pkcs.PublicKeyInfo
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class PublicKeyInfo {
+
+		private AlgorithmIdentifier _algorithm;
+		private byte[] _key;
+
+		// constructors
+
+		// only used in KeyAgreeRecipientInfo.OriginatorIdentifierOrKey.Value
+		// when SubjectIdentifierOrKeyType == PublicKeyInfo
+		internal PublicKeyInfo (AlgorithmIdentifier algorithm, byte[] key) 
+		{
+			_algorithm = algorithm;
+			_key = key;
+		}
+
+		// properties
+
+		public AlgorithmIdentifier Algorithm {
+			get { return _algorithm; }
+		}
+
+		public byte[] KeyValue {
+			get { return _key; }
+		}
+	}
+}
+
+#endif

+ 74 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoCollection.cs

@@ -0,0 +1,74 @@
+//
+// RecipientInfoCollection.cs - System.Security.Cryptography.Pkcs.RecipientInfoCollection
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class RecipientInfoCollection : ICollection {
+
+		private ArrayList _list;
+
+		// only accessible from EnvelopedPkcs7.RecipientInfos
+		internal RecipientInfoCollection () 
+		{
+			_list = new ArrayList ();
+		}
+
+		// properties
+
+		public int Count {
+			get { return _list.Count; }
+		}
+
+		public bool IsSynchronized {
+			get { return _list.IsSynchronized; }
+		}
+
+		public RecipientInfo this [int index] {
+			get { return (RecipientInfo) _list [index]; }
+		}
+
+		public object SyncRoot {
+			get { return _list.SyncRoot; }
+		}
+
+		// methods
+
+		internal int Add (RecipientInfo ri) 
+		{
+			return _list.Add (ri);
+		}
+
+		public void CopyTo (Array array, int index) 
+		{
+			_list.CopyTo (array, index);
+		}
+
+		public void CopyTo (RecipientInfo[] array, int index) 
+		{
+			_list.CopyTo (array, index);
+		}
+
+		public RecipientInfoEnumerator GetEnumerator ()
+		{
+			return new RecipientInfoEnumerator (_list);
+		}
+
+		IEnumerator IEnumerable.GetEnumerator () 
+		{
+			return new RecipientInfoEnumerator (_list);
+		}
+	}
+}
+
+#endif

+ 52 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoEnumerator.cs

@@ -0,0 +1,52 @@
+//
+// RecipientInfoEnumerator.cs - System.Security.Cryptography.Pkcs.RecipientInfoEnumerator
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class RecipientInfoEnumerator : IEnumerator {
+
+		private IEnumerator enumerator;
+
+		// constructors
+
+		internal RecipientInfoEnumerator (IEnumerable enumerable)
+		{
+			enumerator = enumerable.GetEnumerator ();
+		}
+
+		// properties
+
+		public RecipientInfo Current {
+			get { return (RecipientInfo) enumerator.Current; }
+		}
+
+		object IEnumerator.Current {
+			get { return enumerator.Current; }
+		}
+
+		// methods
+
+		public bool MoveNext ()
+		{
+			return enumerator.MoveNext ();
+		}
+
+		public void Reset ()
+		{
+			enumerator.Reset ();
+		}
+	}
+}
+
+#endif

+ 254 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignedPkcs7.cs

@@ -0,0 +1,254 @@
+//
+// SignedPkcs7.cs - System.Security.Cryptography.Pkcs.SignedPkcs7
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Security.Cryptography.X509Certificates;
+using System.Security.Cryptography.Xml;
+using System.Text;
+
+using Mono.Security;
+using Mono.Security.X509;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public sealed class SignedPkcs7 {
+
+		private ContentInfo _content;
+		private bool _detached;
+		private SignerInfoCollection _info;
+		private X509CertificateExCollection _certs;
+		private SubjectIdentifierType _type;
+		private int _version;
+
+		// constructors
+
+		public SignedPkcs7 () 
+		{
+			_certs = new X509CertificateExCollection ();
+			_info = new SignerInfoCollection ();
+		}
+
+		public SignedPkcs7 (ContentInfo content) : this (content, false) {}
+
+		public SignedPkcs7 (ContentInfo content, bool detached) : this ()
+		{
+			if (content == null)
+				throw new ArgumentNullException ("content");
+
+			_content = content;
+			_detached = detached;
+		}
+
+		public SignedPkcs7 (SubjectIdentifierType signerIdentifierType) : this ()
+		{
+			_type = signerIdentifierType;
+			_version = ((_type == SubjectIdentifierType.SubjectKeyIdentifier) ? 2 : 0);
+		}
+
+		public SignedPkcs7 (SubjectIdentifierType signerIdentifierType, ContentInfo content) : this (content, false) 
+		{
+			_type = signerIdentifierType;
+			_version = ((_type == SubjectIdentifierType.SubjectKeyIdentifier) ? 2 : 0);
+		}
+
+		public SignedPkcs7 (SubjectIdentifierType signerIdentifierType, ContentInfo content, bool detached) : this (content, detached) 
+		{
+			_type = signerIdentifierType;
+			_version = ((_type == SubjectIdentifierType.SubjectKeyIdentifier) ? 2 : 0);
+		}
+
+		// properties
+
+		public X509CertificateExCollection Certificates { 
+			get { return _certs; }
+		}
+
+		public ContentInfo ContentInfo { 
+			get { 
+				if (_content == null) {
+					Oid oid = new Oid (PKCS7.data);
+					_content = new ContentInfo (oid, new byte [0]);
+				}
+				return _content; 
+			}
+		}
+
+		public bool Detached { 
+			get { return _detached; }
+		}
+
+		public SignerInfoCollection SignerInfos {
+			get { return _info; }
+		}
+
+		public int Version { 
+			get { return _version; }
+		}
+
+		// methods
+
+		public void CheckSignature (bool verifySignatureOnly)
+		{
+			foreach (SignerInfo si in _info) {
+				si.CheckSignature (verifySignatureOnly);
+			}
+		}
+
+		public void CheckSignature (X509CertificateExCollection extraStore, bool verifySignatureOnly) 
+		{
+			foreach (SignerInfo si in _info) {
+				si.CheckSignature (extraStore, verifySignatureOnly);
+			}
+		}
+
+		[MonoTODO]
+		public void ComputeSignature () 
+		{
+			throw new CryptographicException ("");
+		}
+
+		[MonoTODO]
+		public void ComputeSignature (Pkcs7Signer signer)
+		{
+			ComputeSignature ();
+		}
+
+		private string ToString (byte[] array) 
+		{
+			StringBuilder sb = new StringBuilder ();
+			foreach (byte b in array)
+				sb.Append (b.ToString ("X2"));
+			return sb.ToString ();
+		}
+
+		private byte[] GetKeyIdentifier (Mono.Security.X509.X509Certificate x509) 
+		{
+			// if present in certificate return value of the SubjectKeyIdentifier
+			Mono.Security.X509.X509Extension extn = x509.Extensions ["2.5.29.14"];
+			if (extn != null) {
+				ASN1 bs = new ASN1 (extn.Value.Value);
+				return bs.Value;
+			}
+			// strangely DEPRECATED keyAttributes isn't used here (like KeyUsage)
+
+			// if not then we must calculate the SubjectKeyIdentifier ourselve
+			// Note: MS does that hash on the complete subjectPublicKeyInfo (unlike PKIX)
+			// http://groups.google.ca/groups?selm=e7RqM%24plCHA.1488%40tkmsftngp02&oe=UTF-8&output=gplain
+			ASN1 subjectPublicKeyInfo = new ASN1 (0x30);
+			ASN1 algo = subjectPublicKeyInfo.Add (new ASN1 (0x30));
+			algo.Add (new ASN1 (CryptoConfig.EncodeOID (x509.KeyAlgorithm)));
+			// FIXME: does it work for DSA certs (without an 2.5.29.14 extension ?)
+			algo.Add (new ASN1 (x509.KeyAlgorithmParameters)); 
+			byte[] pubkey = x509.PublicKey;
+			byte[] bsvalue = new byte [pubkey.Length + 1]; // add unused bits (0) before the public key
+			Array.Copy (pubkey, 0, bsvalue, 1, pubkey.Length);
+			subjectPublicKeyInfo.Add (new ASN1 (0x03, bsvalue));
+			SHA1 sha = SHA1.Create ();
+			return sha.ComputeHash (subjectPublicKeyInfo.GetBytes ());
+		}
+
+		[MonoTODO("incomplete - missing attributes")]
+		public void Decode (byte[] encodedMessage) 
+		{
+			PKCS7.ContentInfo ci = new PKCS7.ContentInfo (encodedMessage);
+			if (ci.ContentType != PKCS7.signedData) 
+				throw new Exception ("");
+
+			PKCS7.SignedData sd = new PKCS7.SignedData (ci.Content);
+			SubjectIdentifierType type = SubjectIdentifierType.Unknown;
+			object o = null;
+
+			X509CertificateEx x509 = null;
+			if (sd.SignerInfo.Certificate != null) {
+				x509 = new X509CertificateEx (sd.SignerInfo.Certificate.RawData);
+			}
+			else if ((sd.SignerInfo.IssuerName != null) && (sd.SignerInfo.SerialNumber != null)) {
+				byte[] serial = sd.SignerInfo.SerialNumber;
+				Array.Reverse (serial); // ???
+				type = SubjectIdentifierType.IssuerAndSerialNumber;
+				X509IssuerSerial xis = new X509IssuerSerial ();
+				xis.IssuerName = sd.SignerInfo.IssuerName;
+				xis.SerialNumber = ToString (serial);
+				o = xis;
+				// TODO: move to a FindCertificate (issuer, serial, collection)
+				foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) {
+					if (x.IssuerName == sd.SignerInfo.IssuerName) {
+						if (ToString (x.SerialNumber) == xis.SerialNumber) {
+							x509 = new X509CertificateEx (x.RawData);
+							break;
+						}
+					}
+				}
+			}
+			else if (sd.SignerInfo.SubjectKeyIdentifier != null) {
+				string ski = ToString (sd.SignerInfo.SubjectKeyIdentifier);
+				type = SubjectIdentifierType.SubjectKeyIdentifier;
+				o = (object) ski;
+				// TODO: move to a FindCertificate (ski, collection)
+				foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) {
+					if (ToString (GetKeyIdentifier (x)) == ski) {
+						x509 = new X509CertificateEx (x.RawData);
+						break;
+					}
+				}
+			}
+
+			SignerInfo si = new SignerInfo (sd.SignerInfo.HashName, x509, type, o, sd.SignerInfo.Version);
+			// si.AuthenticatedAttributes
+			// si.UnauthenticatedAttributes
+			_info.Add (si);
+
+			ASN1 content = sd.ContentInfo.Content;
+			Oid oid = new Oid (sd.ContentInfo.ContentType);
+			_content = new ContentInfo (oid, content[0].Value);
+
+			foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) {
+				_certs.Add (new X509CertificateEx (x.RawData));
+			}
+
+			_version = sd.Version;
+		}
+
+		[MonoTODO]
+		public byte[] Encode ()
+		{
+			Mono.Security.X509.X509Certificate x509 = null;
+/*			PKCS7.SignerInfo si = new PKCS7.SignerInfo ();
+			switch (_type) {
+				case SubjectIdentifierType.SubjectKeyIdentifier:
+					si.SubjectKeyIdentifier = GetKeyIdentifier (x509);
+					break;
+				default: 
+					// SubjectIdentifierType.IssuerAndSerialNumber 
+					si.IssuerName = x509.IssuerName;
+					si.SerialNumber = x509.SerialNumber;
+					break;
+			}
+
+			PKCS7.SignedData sd = new PKCS7.SignedData ();
+			sd.Version = _version;
+			sd.SignerInfo = si;
+
+			PKCS7.ContentInfo ci = new PKCS7.ContentInfo (PKCS7.signedData);
+			ci.Content = sd.ASN1;
+			return ci.GetBytes ();*/
+			return null;
+		}
+
+		// counterSsignerInfo -> counterSignerInfo
+		[MonoTODO]
+		public void RemoveSignature (SignerInfo counterSsignerInfo)
+		{
+		}
+	}
+}
+
+#endif

+ 88 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfo.cs

@@ -0,0 +1,88 @@
+//
+// SignerInfo.cs - System.Security.Cryptography.Pkcs.SignerInfo
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class SignerInfo {
+
+		private SubjectIdentifier _signer;
+		private X509CertificateEx _certificate;
+		private Oid _digest;
+		private SignerInfoCollection _counter;
+		private Pkcs9AttributeCollection _auth;
+		private Pkcs9AttributeCollection _unauth;
+		private int _version;
+
+		// only accessible from SignedPkcs7.SignerInfos
+		internal SignerInfo (string hashOid, X509CertificateEx certificate, SubjectIdentifierType type, object o, int version)
+		{
+			_digest = new Oid (hashOid);
+			_certificate = certificate;
+			_counter = new SignerInfoCollection ();
+			_auth = new Pkcs9AttributeCollection ();
+			_unauth = new Pkcs9AttributeCollection ();
+			_signer = new SubjectIdentifier (type, o);
+			_version = version;
+		}
+
+		// properties
+
+		public Pkcs9AttributeCollection AuthenticatedAttributes {
+			get { return _auth; }
+		} 
+
+		public X509CertificateEx Certificate {
+			get { return _certificate; }
+		}
+
+		public SignerInfoCollection CounterSignerInfos {
+			get { return _counter; }
+		}
+
+		public Oid DigestAlgorithm {
+			get { return _digest; }
+		}
+
+		public SubjectIdentifier SignerIdentifier {
+			get { return _signer; }
+		}
+
+		public Pkcs9AttributeCollection UnauthenticatedAttributes {
+			get { return _unauth; }
+		}
+
+		public int Version {
+			get { return _version; }
+		}
+
+		// methods
+
+		[MonoTODO]
+		public void CheckSignature (bool verifySignatureOnly) {}
+
+		[MonoTODO]
+		public void CheckSignature (X509CertificateExCollection extraStore, bool verifySignatureOnly) {}
+
+		[MonoTODO]
+		public void ComputeCounterSignature () {}
+
+		[MonoTODO]
+		public void ComputeCounterSignature (Pkcs7Signer signer) {}
+
+		[MonoTODO]
+		public void RemoveCounterSignature (SignerInfo counterSignerInfo) {}
+	}
+}
+
+#endif

+ 71 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoCollection.cs

@@ -0,0 +1,71 @@
+//
+// SignerInfoCollection.cs - System.Security.Cryptography.Pkcs.SignerInfoCollection
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class SignerInfoCollection : ICollection {
+
+		private ArrayList _list;
+
+		// only accessible from SignedPkcs7.SignerInfos or SignerInfo.CounterSignerInfos
+		internal SignerInfoCollection () 
+		{
+			_list = new ArrayList ();
+		}
+
+		// properties
+
+		public int Count {
+			get { return _list.Count; }
+		}
+
+		public bool IsSynchronized {
+			get { return _list.IsSynchronized; }
+		}
+
+		public SignerInfo this [int index] {
+			get { return (SignerInfo) _list [index]; }
+		}
+
+		public object SyncRoot {
+			get { return _list.SyncRoot; }
+		}
+
+		// methods
+
+		internal void Add (SignerInfo signer) 
+		{
+			_list.Add (signer);
+		}
+
+		public void CopyTo (Array array, int index) 
+		{
+			_list.CopyTo (array, index);
+		}
+
+		public void CopyTo (RecipientInfo[] array, int index) {}
+
+		public SignerInfoEnumerator GetEnumerator ()
+		{
+			return new SignerInfoEnumerator (_list);
+		}
+
+		IEnumerator IEnumerable.GetEnumerator () 
+		{
+			return new SignerInfoEnumerator (_list);
+		}
+	}
+}
+
+#endif

+ 52 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoEnumerator.cs

@@ -0,0 +1,52 @@
+//
+// SignerInfoEnumerator.cs - System.Security.Cryptography.Pkcs.SignerInfoEnumerator
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+using System.Collections;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class SignerInfoEnumerator : IEnumerator {
+
+		private IEnumerator enumerator;
+
+		// constructors
+
+		internal SignerInfoEnumerator (IEnumerable enumerable) 
+		{
+			enumerator = enumerable.GetEnumerator ();
+		}
+
+		// properties
+
+		public SignerInfo Current {
+			get { return (SignerInfo) enumerator.Current; }
+		}
+
+		object IEnumerator.Current {
+			get { return enumerator.Current; }
+		}
+
+		// methods
+
+		public bool MoveNext () 
+		{
+			return enumerator.MoveNext ();
+		}
+
+		public void Reset ()
+		{
+			enumerator.Reset ();
+		}
+	}
+}
+
+#endif

+ 39 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifier.cs

@@ -0,0 +1,39 @@
+//
+// SubjectIdentifier.cs - System.Security.Cryptography.Pkcs.SubjectIdentifier
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class SubjectIdentifier {
+
+		private SubjectIdentifierType _type;
+		private object _value;
+
+		internal SubjectIdentifier (SubjectIdentifierType type, object value)
+		{
+			_type = type;
+			_value = value;
+		}
+
+		// properties
+
+		public SubjectIdentifierType Type {
+			get { return _type; }
+		}
+
+		public object Value {
+			get { return _value; }
+		}
+	}
+}
+
+#endif

+ 39 - 0
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifierOrKey.cs

@@ -0,0 +1,39 @@
+//
+// SubjectIdentifierOrKey.cs - System.Security.Cryptography.Pkcs.SubjectIdentifierOrKey
+//
+// Author:
+//	Sebastien Pouliot ([email protected])
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+
+#if NET_1_2
+
+using System;
+
+namespace System.Security.Cryptography.Pkcs {
+
+	public class SubjectIdentifierOrKey {
+
+		private SubjectIdentifierOrKeyType _type;
+		private object _value;
+
+		internal SubjectIdentifierOrKey (SubjectIdentifierOrKeyType type, object value)
+		{
+			_type = type;
+			_value = value;
+		}
+
+		// properties
+
+		public SubjectIdentifierOrKeyType Type {
+			get { return _type; }
+		}
+
+		public object Value {
+			get { return _value; }
+		}
+	}
+}
+
+#endif