diff --git a/crypto/src/asn1/smime/SMIMEAttributes.cs b/crypto/src/asn1/smime/SMIMEAttributes.cs
new file mode 100644
index 000000000..e154e5e74
--- /dev/null
+++ b/crypto/src/asn1/smime/SMIMEAttributes.cs
@@ -0,0 +1,11 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ public abstract class SmimeAttributes
+ {
+ public static readonly DerObjectIdentifier SmimeCapabilities = PkcsObjectIdentifiers.Pkcs9AtSmimeCapabilities;
+ public static readonly DerObjectIdentifier EncrypKeyPref = PkcsObjectIdentifiers.IdAAEncrypKeyPref;
+ }
+}
diff --git a/crypto/src/asn1/smime/SMIMECapabilities.cs b/crypto/src/asn1/smime/SMIMECapabilities.cs
new file mode 100644
index 000000000..ca3c3af7d
--- /dev/null
+++ b/crypto/src/asn1/smime/SMIMECapabilities.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ /**
+ * Handler class for dealing with S/MIME Capabilities
+ */
+ public class SmimeCapabilities
+ : Asn1Encodable
+ {
+ /**
+ * general preferences
+ */
+ public static readonly DerObjectIdentifier PreferSignedData = PkcsObjectIdentifiers.PreferSignedData;
+ public static readonly DerObjectIdentifier CannotDecryptAny = PkcsObjectIdentifiers.CannotDecryptAny;
+ public static readonly DerObjectIdentifier SmimeCapabilitesVersions = PkcsObjectIdentifiers.SmimeCapabilitiesVersions;
+
+ /**
+ * encryption algorithms preferences
+ */
+ public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7");
+ public static readonly DerObjectIdentifier DesEde3Cbc = PkcsObjectIdentifiers.DesEde3Cbc;
+ public static readonly DerObjectIdentifier RC2Cbc = PkcsObjectIdentifiers.RC2Cbc;
+
+ private Asn1Sequence capabilities;
+
+ /**
+ * return an Attr object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception ArgumentException if the object cannot be converted.
+ */
+ public static SmimeCapabilities GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is SmimeCapabilities)
+ {
+ return (SmimeCapabilities) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SmimeCapabilities((Asn1Sequence) obj);
+ }
+
+ if (obj is AttributeX509)
+ {
+ return new SmimeCapabilities(
+ (Asn1Sequence)(((AttributeX509) obj).AttrValues[0]));
+ }
+
+ throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+ }
+
+ public SmimeCapabilities(
+ Asn1Sequence seq)
+ {
+ capabilities = seq;
+ }
+
+#if !SILVERLIGHT
+ [Obsolete("Use 'GetCapabilitiesForOid' instead")]
+ public ArrayList GetCapabilities(
+ DerObjectIdentifier capability)
+ {
+ ArrayList list = new ArrayList();
+ DoGetCapabilitiesForOid(capability, list);
+ return list;
+ }
+#endif
+
+ /**
+ * returns an ArrayList with 0 or more objects of all the capabilities
+ * matching the passed in capability Oid. If the Oid passed is null the
+ * entire set is returned.
+ */
+ public IList GetCapabilitiesForOid(
+ DerObjectIdentifier capability)
+ {
+ IList list = Platform.CreateArrayList();
+ DoGetCapabilitiesForOid(capability, list);
+ return list;
+ }
+
+ private void DoGetCapabilitiesForOid(DerObjectIdentifier capability, IList list)
+ {
+ if (capability == null)
+ {
+ foreach (object o in capabilities)
+ {
+ SmimeCapability cap = SmimeCapability.GetInstance(o);
+
+ list.Add(cap);
+ }
+ }
+ else
+ {
+ foreach (object o in capabilities)
+ {
+ SmimeCapability cap = SmimeCapability.GetInstance(o);
+
+ if (capability.Equals(cap.CapabilityID))
+ {
+ list.Add(cap);
+ }
+ }
+ }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ * <pre>
+ * SMIMECapabilities ::= Sequence OF SMIMECapability
+ * </pre>
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ return capabilities;
+ }
+ }
+}
diff --git a/crypto/src/asn1/smime/SMIMECapabilitiesAttribute.cs b/crypto/src/asn1/smime/SMIMECapabilitiesAttribute.cs
new file mode 100644
index 000000000..310c478fe
--- /dev/null
+++ b/crypto/src/asn1/smime/SMIMECapabilitiesAttribute.cs
@@ -0,0 +1,16 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ public class SmimeCapabilitiesAttribute
+ : AttributeX509
+ {
+ public SmimeCapabilitiesAttribute(
+ SmimeCapabilityVector capabilities)
+ : base(SmimeAttributes.SmimeCapabilities,
+ new DerSet(new DerSequence(capabilities.ToAsn1EncodableVector())))
+ {
+ }
+ }
+}
diff --git a/crypto/src/asn1/smime/SMIMECapability.cs b/crypto/src/asn1/smime/SMIMECapability.cs
new file mode 100644
index 000000000..5709cb815
--- /dev/null
+++ b/crypto/src/asn1/smime/SMIMECapability.cs
@@ -0,0 +1,101 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ public class SmimeCapability
+ : Asn1Encodable
+ {
+ /**
+ * general preferences
+ */
+ public static readonly DerObjectIdentifier PreferSignedData = PkcsObjectIdentifiers.PreferSignedData;
+ public static readonly DerObjectIdentifier CannotDecryptAny = PkcsObjectIdentifiers.CannotDecryptAny;
+ public static readonly DerObjectIdentifier SmimeCapabilitiesVersions = PkcsObjectIdentifiers.SmimeCapabilitiesVersions;
+
+ /**
+ * encryption algorithms preferences
+ */
+ public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7");
+ public static readonly DerObjectIdentifier DesEde3Cbc = PkcsObjectIdentifiers.DesEde3Cbc;
+ public static readonly DerObjectIdentifier RC2Cbc = PkcsObjectIdentifiers.RC2Cbc;
+
+ private DerObjectIdentifier capabilityID;
+ private Asn1Object parameters;
+
+ public SmimeCapability(
+ Asn1Sequence seq)
+ {
+ capabilityID = (DerObjectIdentifier) seq[0].ToAsn1Object();
+
+ if (seq.Count > 1)
+ {
+ parameters = seq[1].ToAsn1Object();
+ }
+ }
+
+ public SmimeCapability(
+ DerObjectIdentifier capabilityID,
+ Asn1Encodable parameters)
+ {
+ if (capabilityID == null)
+ throw new ArgumentNullException("capabilityID");
+
+ this.capabilityID = capabilityID;
+
+ if (parameters != null)
+ {
+ this.parameters = parameters.ToAsn1Object();
+ }
+ }
+
+ public static SmimeCapability GetInstance(
+ object obj)
+ {
+ if (obj == null || obj is SmimeCapability)
+ {
+ return (SmimeCapability) obj;
+ }
+
+ if (obj is Asn1Sequence)
+ {
+ return new SmimeCapability((Asn1Sequence) obj);
+ }
+
+ throw new ArgumentException("Invalid SmimeCapability");
+ }
+
+ public DerObjectIdentifier CapabilityID
+ {
+ get { return capabilityID; }
+ }
+
+ public Asn1Object Parameters
+ {
+ get { return parameters; }
+ }
+
+ /**
+ * Produce an object suitable for an Asn1OutputStream.
+ * <pre>
+ * SMIMECapability ::= Sequence {
+ * capabilityID OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY capabilityID OPTIONAL
+ * }
+ * </pre>
+ */
+ public override Asn1Object ToAsn1Object()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(capabilityID);
+
+ if (parameters != null)
+ {
+ v.Add(parameters);
+ }
+
+ return new DerSequence(v);
+ }
+ }
+}
diff --git a/crypto/src/asn1/smime/SMIMECapabilityVector.cs b/crypto/src/asn1/smime/SMIMECapabilityVector.cs
new file mode 100644
index 000000000..842825b88
--- /dev/null
+++ b/crypto/src/asn1/smime/SMIMECapabilityVector.cs
@@ -0,0 +1,37 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ /**
+ * Handler for creating a vector S/MIME Capabilities
+ */
+ public class SmimeCapabilityVector
+ {
+ private readonly Asn1EncodableVector capabilities = new Asn1EncodableVector();
+
+ public void AddCapability(
+ DerObjectIdentifier capability)
+ {
+ capabilities.Add(new DerSequence(capability));
+ }
+
+ public void AddCapability(
+ DerObjectIdentifier capability,
+ int value)
+ {
+ capabilities.Add(new DerSequence(capability, new DerInteger(value)));
+ }
+
+ public void AddCapability(
+ DerObjectIdentifier capability,
+ Asn1Encodable parameters)
+ {
+ capabilities.Add(new DerSequence(capability, parameters));
+ }
+
+ public Asn1EncodableVector ToAsn1EncodableVector()
+ {
+ return capabilities;
+ }
+ }
+}
diff --git a/crypto/src/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs b/crypto/src/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs
new file mode 100644
index 000000000..19c5fd78a
--- /dev/null
+++ b/crypto/src/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs
@@ -0,0 +1,44 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Smime
+{
+ /**
+ * The SmimeEncryptionKeyPreference object.
+ * <pre>
+ * SmimeEncryptionKeyPreference ::= CHOICE {
+ * issuerAndSerialNumber [0] IssuerAndSerialNumber,
+ * receipentKeyId [1] RecipientKeyIdentifier,
+ * subjectAltKeyIdentifier [2] SubjectKeyIdentifier
+ * }
+ * </pre>
+ */
+ public class SmimeEncryptionKeyPreferenceAttribute
+ : AttributeX509
+ {
+ public SmimeEncryptionKeyPreferenceAttribute(
+ IssuerAndSerialNumber issAndSer)
+ : base(SmimeAttributes.EncrypKeyPref,
+ new DerSet(new DerTaggedObject(false, 0, issAndSer)))
+ {
+ }
+
+ public SmimeEncryptionKeyPreferenceAttribute(
+ RecipientKeyIdentifier rKeyID)
+ : base(SmimeAttributes.EncrypKeyPref,
+ new DerSet(new DerTaggedObject(false, 1, rKeyID)))
+ {
+ }
+
+ /**
+ * @param sKeyId the subjectKeyIdentifier value (normally the X.509 one)
+ */
+ public SmimeEncryptionKeyPreferenceAttribute(
+ Asn1OctetString sKeyID)
+ : base(SmimeAttributes.EncrypKeyPref,
+ new DerSet(new DerTaggedObject(false, 2, sKeyID)))
+ {
+ }
+ }
+}
|