2003-12-07 Sebastien Pouliot <spouliot@videotron.ca>
authorSebastien Pouliot <sebastien@ximian.com>
Mon, 8 Dec 2003 01:20:50 +0000 (01:20 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Mon, 8 Dec 2003 01:20:50 +0000 (01:20 -0000)
* 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

19 files changed:
mcs/class/System.Security/System.Security.Cryptography.Pkcs/ChangeLog
mcs/class/System.Security/System.Security.Cryptography.Pkcs/ContentInfo.cs
mcs/class/System.Security/System.Security.Cryptography.Pkcs/EnvelopedPkcs7.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyAgreeRecipientInfo.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyTransRecipientInfo.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7Recipient.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientCollection.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientEnumerator.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeCollection.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeEnumerator.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/PublicKeyInfo.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoCollection.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoEnumerator.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignedPkcs7.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfo.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoCollection.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoEnumerator.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifier.cs [new file with mode: 0755]
mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifierOrKey.cs [new file with mode: 0755]

index 0a880b2bd3f942bc62340b45f59beac837db6ba1..9892c677c329349880d81928a96618f5a33dfd99 100755 (executable)
@@ -1,3 +1,36 @@
+2003-12-07  Sebastien Pouliot  <spouliot@videotron.ca>
+
+       * 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  <spouliot@videotron.ca>
 
        * ContentInfo.cs: New. Class to encapsulate PKCS7 ContentInfo. Static 
index d8f355337fc4e54894a6f5a27b59059d9867332b..b80d6cfc83fcc0a2b51709d2739d5e1f5d878823 100755 (executable)
@@ -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);
                        }
                }
        }
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/EnvelopedPkcs7.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/EnvelopedPkcs7.cs
new file mode 100755 (executable)
index 0000000..012759e
--- /dev/null
@@ -0,0 +1,226 @@
+//
+// EnvelopedPkcs7.cs - System.Security.Cryptography.Pkcs.EnvelopedPkcs7
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyAgreeRecipientInfo.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyAgreeRecipientInfo.cs
new file mode 100755 (executable)
index 0000000..6e371d7
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// KeyAgreeRecipientInfo.cs - System.Security.Cryptography.Pkcs.KeyAgreeRecipientInfo
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyTransRecipientInfo.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/KeyTransRecipientInfo.cs
new file mode 100755 (executable)
index 0000000..f6833ed
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// KeyTransRecipientInfo.cs - System.Security.Cryptography.Pkcs.KeyTransRecipientInfo
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7Recipient.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7Recipient.cs
new file mode 100755 (executable)
index 0000000..0d4e86f
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// Pkcs7Recipient.cs - System.Security.Cryptography.Pkcs.Pkcs7Recipient
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientCollection.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientCollection.cs
new file mode 100755 (executable)
index 0000000..c64c265
--- /dev/null
@@ -0,0 +1,94 @@
+//
+// Pkcs7RecipientCollection.cs - System.Security.Cryptography.Pkcs.Pkcs7RecipientCollection
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientEnumerator.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs7RecipientEnumerator.cs
new file mode 100755 (executable)
index 0000000..129b61a
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// Pkcs7RecipientEnumerator.cs - System.Security.Cryptography.Pkcs.Pkcs7RecipientEnumerator
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeCollection.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeCollection.cs
new file mode 100755 (executable)
index 0000000..6186c58
--- /dev/null
@@ -0,0 +1,78 @@
+//
+// Pkcs9AttributeCollection.cs - System.Security.Cryptography.Pkcs.Pkcs9AttributeCollection
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeEnumerator.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/Pkcs9AttributeEnumerator.cs
new file mode 100755 (executable)
index 0000000..a169f5b
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// Pkcs9AttributeEnumerator.cs - System.Security.Cryptography.Pkcs.Pkcs9AttributeEnumerator
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/PublicKeyInfo.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/PublicKeyInfo.cs
new file mode 100755 (executable)
index 0000000..dd43124
--- /dev/null
@@ -0,0 +1,43 @@
+//
+// PublicKeyInfo.cs - System.Security.Cryptography.Pkcs.PublicKeyInfo
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoCollection.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoCollection.cs
new file mode 100755 (executable)
index 0000000..fdfc80d
--- /dev/null
@@ -0,0 +1,74 @@
+//
+// RecipientInfoCollection.cs - System.Security.Cryptography.Pkcs.RecipientInfoCollection
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoEnumerator.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/RecipientInfoEnumerator.cs
new file mode 100755 (executable)
index 0000000..bbecdec
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// RecipientInfoEnumerator.cs - System.Security.Cryptography.Pkcs.RecipientInfoEnumerator
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignedPkcs7.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignedPkcs7.cs
new file mode 100755 (executable)
index 0000000..a442637
--- /dev/null
@@ -0,0 +1,254 @@
+//
+// SignedPkcs7.cs - System.Security.Cryptography.Pkcs.SignedPkcs7
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfo.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfo.cs
new file mode 100755 (executable)
index 0000000..0058ac5
--- /dev/null
@@ -0,0 +1,88 @@
+//
+// SignerInfo.cs - System.Security.Cryptography.Pkcs.SignerInfo
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoCollection.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoCollection.cs
new file mode 100755 (executable)
index 0000000..8749394
--- /dev/null
@@ -0,0 +1,71 @@
+//
+// SignerInfoCollection.cs - System.Security.Cryptography.Pkcs.SignerInfoCollection
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoEnumerator.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SignerInfoEnumerator.cs
new file mode 100755 (executable)
index 0000000..f9be57e
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// SignerInfoEnumerator.cs - System.Security.Cryptography.Pkcs.SignerInfoEnumerator
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifier.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifier.cs
new file mode 100755 (executable)
index 0000000..750c02f
--- /dev/null
@@ -0,0 +1,39 @@
+//
+// SubjectIdentifier.cs - System.Security.Cryptography.Pkcs.SubjectIdentifier
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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
\ No newline at end of file
diff --git a/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifierOrKey.cs b/mcs/class/System.Security/System.Security.Cryptography.Pkcs/SubjectIdentifierOrKey.cs
new file mode 100755 (executable)
index 0000000..6608c7e
--- /dev/null
@@ -0,0 +1,39 @@
+//
+// SubjectIdentifierOrKey.cs - System.Security.Cryptography.Pkcs.SubjectIdentifierOrKey
+//
+// Author:
+//     Sebastien Pouliot (spouliot@motus.com)
+//
+// (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