* 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
+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
// 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)
{
// 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);
}
}
}
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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