summary refs log tree commit diff
path: root/crypto/src/asn1/isismtt
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/asn1/isismtt')
-rw-r--r--crypto/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs177
-rw-r--r--crypto/src/asn1/isismtt/ocsp/CertHash.cs121
-rw-r--r--crypto/src/asn1/isismtt/ocsp/RequestedCertificate.cs186
-rw-r--r--crypto/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs70
-rw-r--r--crypto/src/asn1/isismtt/x509/AdmissionSyntax.csbin20844 -> 11549 bytes
-rw-r--r--crypto/src/asn1/isismtt/x509/Admissions.cs186
-rw-r--r--crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs170
-rw-r--r--crypto/src/asn1/isismtt/x509/MonetaryLimit.cs121
-rw-r--r--crypto/src/asn1/isismtt/x509/NamingAuthority.cs214
-rw-r--r--crypto/src/asn1/isismtt/x509/ProcurationSyntax.cs232
-rw-r--r--crypto/src/asn1/isismtt/x509/ProfessionInfo.cs386
-rw-r--r--crypto/src/asn1/isismtt/x509/Restriction.cs81
12 files changed, 1944 insertions, 0 deletions
diff --git a/crypto/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs b/crypto/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs
new file mode 100644
index 000000000..af60b030a
--- /dev/null
+++ b/crypto/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs
@@ -0,0 +1,177 @@
+namespace Org.BouncyCastle.Asn1.IsisMtt
+{
+	public abstract class IsisMttObjectIdentifiers
+	{
+		public static readonly DerObjectIdentifier IdIsisMtt = new DerObjectIdentifier("1.3.36.8");
+
+		public static readonly DerObjectIdentifier IdIsisMttCP = new DerObjectIdentifier(IdIsisMtt + ".1");
+
+		/**
+		 * The id-isismtt-cp-accredited OID indicates that the certificate is a
+		 * qualified certificate according to Directive 1999/93/EC of the European
+		 * Parliament and of the Council of 13 December 1999 on a Community
+		 * Framework for Electronic Signatures, which additionally conforms the
+		 * special requirements of the SigG and has been issued by an accredited CA.
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttCPAccredited = new DerObjectIdentifier(IdIsisMttCP + ".1");
+
+		public static readonly DerObjectIdentifier IdIsisMttAT = new DerObjectIdentifier(IdIsisMtt + ".3");
+
+		/**
+		 * Certificate extensionDate of certificate generation
+		 * 
+		 * <pre>
+		 *		DateOfCertGenSyntax ::= GeneralizedTime
+		 * </pre>
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATDateOfCertGen = new DerObjectIdentifier(IdIsisMttAT + ".1");
+
+		/**
+		 * Attribute to indicate that the certificate holder may sign in the name of
+		 * a third person. May also be used as extension in a certificate.
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATProcuration = new DerObjectIdentifier(IdIsisMttAT + ".2");
+
+		/**
+		 * Attribute to indicate admissions to certain professions. May be used as
+		 * attribute in attribute certificate or as extension in a certificate
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATAdmission = new DerObjectIdentifier(IdIsisMttAT + ".3");
+
+		/**
+		 * Monetary limit for transactions. The QcEuMonetaryLimit QC statement MUST
+		 * be used in new certificates in place of the extension/attribute
+		 * MonetaryLimit since January 1, 2004. For the sake of backward
+		 * compatibility with certificates already in use, SigG conforming
+		 * components MUST support MonetaryLimit (as well as QcEuLimitValue).
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATMonetaryLimit = new DerObjectIdentifier(IdIsisMttAT + ".4");
+
+		/**
+		 * A declaration of majority. May be used as attribute in attribute
+		 * certificate or as extension in a certificate
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATDeclarationOfMajority = new DerObjectIdentifier(IdIsisMttAT + ".5");
+
+		/**
+		 * 
+		 * Serial number of the smart card containing the corresponding private key
+		 * 
+		 * <pre>
+		 *		ICCSNSyntax ::= OCTET STRING (SIZE(8..20))
+		 * </pre>
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATIccsn = new DerObjectIdentifier(IdIsisMttAT + ".6");
+
+		/**
+		 * 
+		 * Reference for a file of a smartcard that stores the public key of this
+		 * certificate and that is used as �security anchor�.
+		 * 
+		 * <pre>
+		 *		PKReferenceSyntax ::= OCTET STRING (SIZE(20))
+		 * </pre>
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATPKReference = new DerObjectIdentifier(IdIsisMttAT + ".7");
+
+		/**
+		 * Some other restriction regarding the usage of this certificate. May be
+		 * used as attribute in attribute certificate or as extension in a
+		 * certificate.
+		 * 
+		 * <pre>
+		 *		RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+		 * </pre>
+		 * 
+		 * @see Org.BouncyCastle.Asn1.IsisMtt.X509.Restriction
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATRestriction = new DerObjectIdentifier(IdIsisMttAT + ".8");
+
+		/**
+		 * 
+		 * (Single)Request extension: Clients may include this extension in a
+		 * (single) Request to request the responder to send the certificate in the
+		 * response message along with the status information. Besides the LDAP
+		 * service, this extension provides another mechanism for the distribution
+		 * of certificates, which MAY optionally be provided by certificate
+		 * repositories.
+		 * 
+		 * <pre>
+		 *		RetrieveIfAllowed ::= BOOLEAN
+		 * </pre>
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATRetrieveIfAllowed = new DerObjectIdentifier(IdIsisMttAT + ".9");
+
+		/**
+		 * SingleOCSPResponse extension: The certificate requested by the client by
+		 * inserting the RetrieveIfAllowed extension in the request, will be
+		 * returned in this extension.
+		 * 
+		 * @see Org.BouncyCastle.Asn1.IsisMtt.Ocsp.RequestedCertificate
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATRequestedCertificate = new DerObjectIdentifier(IdIsisMttAT + ".10");
+
+		/**
+		 * Base ObjectIdentifier for naming authorities
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATNamingAuthorities = new DerObjectIdentifier(IdIsisMttAT + ".11");
+
+		/**
+		 * SingleOCSPResponse extension: Date, when certificate has been published
+		 * in the directory and status information has become available. Currently,
+		 * accrediting authorities enforce that SigG-conforming OCSP servers include
+		 * this extension in the responses.
+		 * 
+		 * <pre>
+		 *		CertInDirSince ::= GeneralizedTime
+		 * </pre>
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATCertInDirSince = new DerObjectIdentifier(IdIsisMttAT + ".12");
+
+		/**
+		 * Hash of a certificate in OCSP.
+		 *
+		 * @see Org.BouncyCastle.Asn1.IsisMtt.Ocsp.CertHash
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATCertHash = new DerObjectIdentifier(IdIsisMttAT + ".13");
+
+		/**
+		 * <pre>
+		 *		NameAtBirth ::= DirectoryString(SIZE(1..64)
+		 * </pre>
+		 * 
+		 * Used in
+		 * {@link Org.BouncyCastle.Asn1.X509.SubjectDirectoryAttributes SubjectDirectoryAttributes}
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATNameAtBirth = new DerObjectIdentifier(IdIsisMttAT + ".14");
+
+		/**
+		 * Some other information of non-restrictive nature regarding the usage of
+		 * this certificate. May be used as attribute in atribute certificate or as
+		 * extension in a certificate.
+		 * 
+		 * <pre>
+		 *               AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+		 * </pre>
+		 * 
+		 * @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdditionalInformationSyntax
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATAdditionalInformation = new DerObjectIdentifier(IdIsisMttAT + ".15");
+
+		/**
+		 * Indicates that an attribute certificate exists, which limits the
+		 * usability of this public key certificate. Whenever verifying a signature
+		 * with the help of this certificate, the content of the corresponding
+		 * attribute certificate should be concerned. This extension MUST be
+		 * included in a PKC, if a corresponding attribute certificate (having the
+		 * PKC as base certificate) contains some attribute that restricts the
+		 * usability of the PKC too. Attribute certificates with restricting content
+		 * MUST always be included in the signed document.
+		 * 
+		 * <pre>
+		 *		LiabilityLimitationFlagSyntax ::= BOOLEAN
+		 * </pre>
+		 */
+		public static readonly DerObjectIdentifier IdIsisMttATLiabilityLimitationFlag = new DerObjectIdentifier("0.2.262.1.10.12.0");
+	}
+}
diff --git a/crypto/src/asn1/isismtt/ocsp/CertHash.cs b/crypto/src/asn1/isismtt/ocsp/CertHash.cs
new file mode 100644
index 000000000..da5b530e4
--- /dev/null
+++ b/crypto/src/asn1/isismtt/ocsp/CertHash.cs
@@ -0,0 +1,121 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.Ocsp
+{
+	/**
+	* ISIS-MTT PROFILE: The responder may include this extension in a response to
+	* send the hash of the requested certificate to the responder. This hash is
+	* cryptographically bound to the certificate and serves as evidence that the
+	* certificate is known to the responder (i.e. it has been issued and is present
+	* in the directory). Hence, this extension is a means to provide a positive
+	* statement of availability as described in T8.[8]. As explained in T13.[1],
+	* clients may rely on this information to be able to validate signatures after
+	* the expiry of the corresponding certificate. Hence, clients MUST support this
+	* extension. If a positive statement of availability is to be delivered, this
+	* extension syntax and OID MUST be used.
+	* <p/>
+	* <p/>
+	* <pre>
+	*     CertHash ::= SEQUENCE {
+	*       hashAlgorithm AlgorithmIdentifier,
+	*       certificateHash OCTET STRING
+	*     }
+	* </pre>
+	*/
+	public class CertHash
+		: Asn1Encodable
+	{
+		private readonly AlgorithmIdentifier	hashAlgorithm;
+		private readonly byte[]					certificateHash;
+
+		public static CertHash GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is CertHash)
+			{
+				return (CertHash) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new CertHash((Asn1Sequence) obj);
+			}
+
+			throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+		}
+
+		/**
+		* Constructor from Asn1Sequence.
+		* <p/>
+		* The sequence is of type CertHash:
+		* <p/>
+		* <pre>
+		*     CertHash ::= SEQUENCE {
+		*       hashAlgorithm AlgorithmIdentifier,
+		*       certificateHash OCTET STRING
+		*     }
+		* </pre>
+		*
+		* @param seq The ASN.1 sequence.
+		*/
+		private CertHash(
+			Asn1Sequence seq)
+		{
+			if (seq.Count != 2)
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+			this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]);
+			this.certificateHash = DerOctetString.GetInstance(seq[1]).GetOctets();
+		}
+
+		/**
+		* Constructor from a given details.
+		*
+		* @param hashAlgorithm   The hash algorithm identifier.
+		* @param certificateHash The hash of the whole DER encoding of the certificate.
+		*/
+		public CertHash(
+			AlgorithmIdentifier	hashAlgorithm,
+			byte[]				certificateHash)
+		{
+			if (hashAlgorithm == null)
+				throw new ArgumentNullException("hashAlgorithm");
+			if (certificateHash == null)
+				throw new ArgumentNullException("certificateHash");
+
+			this.hashAlgorithm = hashAlgorithm;
+			this.certificateHash = (byte[]) certificateHash.Clone();
+		}
+
+		public AlgorithmIdentifier HashAlgorithm
+		{
+			get { return hashAlgorithm; }
+		}
+
+		public byte[] CertificateHash
+		{
+			get { return (byte[]) certificateHash.Clone(); }
+		}
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*     CertHash ::= SEQUENCE {
+		*       hashAlgorithm AlgorithmIdentifier,
+		*       certificateHash OCTET STRING
+		*     }
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			return new DerSequence(hashAlgorithm, new DerOctetString(certificateHash));
+		}
+	}
+}
diff --git a/crypto/src/asn1/isismtt/ocsp/RequestedCertificate.cs b/crypto/src/asn1/isismtt/ocsp/RequestedCertificate.cs
new file mode 100644
index 000000000..7724bfed6
--- /dev/null
+++ b/crypto/src/asn1/isismtt/ocsp/RequestedCertificate.cs
@@ -0,0 +1,186 @@
+using System;
+using System.IO;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.Ocsp
+{
+	/**
+	* ISIS-MTT-Optional: The certificate requested by the client by inserting the
+	* RetrieveIfAllowed extension in the request, will be returned in this
+	* extension.
+	* <p/>
+	* ISIS-MTT-SigG: The signature act allows publishing certificates only then,
+	* when the certificate owner gives his isExplicit permission. Accordingly, there
+	* may be �nondownloadable� certificates, about which the responder must provide
+	* status information, but MUST NOT include them in the response. Clients may
+	* get therefore the following three kind of answers on a single request
+	* including the RetrieveIfAllowed extension:
+	* <ul>
+	* <li> a) the responder supports the extension and is allowed to publish the
+	* certificate: RequestedCertificate returned including the requested
+	* certificate</li>
+	* <li>b) the responder supports the extension but is NOT allowed to publish
+	* the certificate: RequestedCertificate returned including an empty OCTET
+	* STRING</li>
+	* <li>c) the responder does not support the extension: RequestedCertificate is
+	* not included in the response</li>
+	* </ul>
+	* Clients requesting RetrieveIfAllowed MUST be able to handle these cases. If
+	* any of the OCTET STRING options is used, it MUST contain the DER encoding of
+	* the requested certificate.
+	* <p/>
+	* <pre>
+	*            RequestedCertificate ::= CHOICE {
+	*              Certificate Certificate,
+	*              publicKeyCertificate [0] EXPLICIT OCTET STRING,
+	*              attributeCertificate [1] EXPLICIT OCTET STRING
+	*            }
+	* </pre>
+	*/
+	public class RequestedCertificate
+		: Asn1Encodable, IAsn1Choice
+	{
+		public enum Choice
+		{
+			Certificate = -1,
+			PublicKeyCertificate = 0,
+			AttributeCertificate = 1
+		}
+
+		private readonly X509CertificateStructure	cert;
+		private readonly byte[]						publicKeyCert;
+		private readonly byte[]						attributeCert;
+
+		public static RequestedCertificate GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is RequestedCertificate)
+			{
+				return (RequestedCertificate) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new RequestedCertificate(X509CertificateStructure.GetInstance(obj));
+			}
+
+			if (obj is Asn1TaggedObject)
+			{
+				return new RequestedCertificate((Asn1TaggedObject) obj);
+			}
+
+			throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+		}
+
+		public static RequestedCertificate GetInstance(
+			Asn1TaggedObject	obj,
+			bool				isExplicit)
+		{
+			if (!isExplicit)
+				throw new ArgumentException("choice item must be explicitly tagged");
+
+			return GetInstance(obj.GetObject());
+		}
+
+		private RequestedCertificate(
+			Asn1TaggedObject tagged)
+		{
+			switch ((Choice) tagged.TagNo)
+			{
+				case Choice.AttributeCertificate:
+					this.attributeCert = Asn1OctetString.GetInstance(tagged, true).GetOctets();
+					break;
+				case Choice.PublicKeyCertificate:
+					this.publicKeyCert = Asn1OctetString.GetInstance(tagged, true).GetOctets();
+					break;
+				default:
+					throw new ArgumentException("unknown tag number: " + tagged.TagNo);
+			}
+		}
+
+		/**
+		* Constructor from a given details.
+		* <p/>
+		* Only one parameter can be given. All other must be <code>null</code>.
+		*
+		* @param certificate Given as Certificate
+		*/
+		public RequestedCertificate(
+			X509CertificateStructure certificate)
+		{
+			this.cert = certificate;
+		}
+
+		public RequestedCertificate(
+			Choice	type,
+			byte[]	certificateOctets)
+			: this(new DerTaggedObject((int) type, new DerOctetString(certificateOctets)))
+		{
+		}
+
+		public Choice Type
+		{
+			get
+			{
+				if (cert != null)
+					return Choice.Certificate;
+
+				if (publicKeyCert != null)
+					return Choice.PublicKeyCertificate;
+
+				return Choice.AttributeCertificate;
+			}
+		}
+
+		public byte[] GetCertificateBytes()
+		{
+			if (cert != null)
+			{
+				try
+				{
+					return cert.GetEncoded();
+				}
+				catch (IOException e)
+				{
+					throw new InvalidOperationException("can't decode certificate: " + e);
+				}
+			}
+
+			if (publicKeyCert != null)
+				return publicKeyCert;
+
+			return attributeCert;
+		}
+    
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*            RequestedCertificate ::= CHOICE {
+		*              Certificate Certificate,
+		*              publicKeyCertificate [0] EXPLICIT OCTET STRING,
+		*              attributeCertificate [1] EXPLICIT OCTET STRING
+		*            }
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			if (publicKeyCert != null)
+			{
+				return new DerTaggedObject(0, new DerOctetString(publicKeyCert));
+			}
+
+			if (attributeCert != null)
+			{
+				return new DerTaggedObject(1, new DerOctetString(attributeCert));
+			}
+
+			return cert.ToAsn1Object();
+		}
+	}
+}
diff --git a/crypto/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs b/crypto/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs
new file mode 100644
index 000000000..f81d459c6
--- /dev/null
+++ b/crypto/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs
@@ -0,0 +1,70 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+	/**
+	* Some other information of non-restrictive nature regarding the usage of this
+	* certificate.
+	* 
+	* <pre>
+	*    AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+	* </pre>
+	*/
+	public class AdditionalInformationSyntax
+		: Asn1Encodable
+	{
+		private readonly DirectoryString information;
+
+		public static AdditionalInformationSyntax GetInstance(
+			object obj)
+		{
+			if (obj is AdditionalInformationSyntax)
+				return (AdditionalInformationSyntax) obj;
+
+			if (obj is IAsn1String)
+				return new AdditionalInformationSyntax(DirectoryString.GetInstance(obj));
+
+			throw new ArgumentException("Unknown object in GetInstance: " + obj.GetType().Name, "obj");
+		}
+
+		private AdditionalInformationSyntax(
+			DirectoryString information)
+		{
+			this.information = information;
+		}
+
+		/**
+		* Constructor from a given details.
+		*
+		* @param information The describtion of the information.
+		*/
+		public AdditionalInformationSyntax(
+			string information)
+		{
+			this.information = new DirectoryString(information);
+		}
+
+		public virtual DirectoryString Information
+		{
+			get { return information; }
+		}
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*   AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			return information.ToAsn1Object();
+		}
+	}
+}
diff --git a/crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs b/crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs
index f322ef88f..64b5dbec8 100644
--- a/crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs
+++ b/crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs
Binary files differdiff --git a/crypto/src/asn1/isismtt/x509/Admissions.cs b/crypto/src/asn1/isismtt/x509/Admissions.cs
new file mode 100644
index 000000000..40290c608
--- /dev/null
+++ b/crypto/src/asn1/isismtt/x509/Admissions.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+	/**
+	* An Admissions structure.
+	* <p/>
+	* <pre>
+	*            Admissions ::= SEQUENCE
+	*            {
+	*              admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
+	*              namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
+	*              professionInfos SEQUENCE OF ProfessionInfo
+	*            }
+	* <p/>
+	* </pre>
+	*
+	* @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdmissionSyntax
+	* @see Org.BouncyCastle.Asn1.IsisMtt.X509.ProfessionInfo
+	* @see Org.BouncyCastle.Asn1.IsisMtt.X509.NamingAuthority
+	*/
+	public class Admissions
+		: Asn1Encodable
+	{
+		private readonly GeneralName		admissionAuthority;
+		private readonly NamingAuthority	namingAuthority;
+		private readonly Asn1Sequence		professionInfos;
+
+		public static Admissions GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is Admissions)
+			{
+				return (Admissions) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new Admissions((Asn1Sequence) obj);
+			}
+
+			throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+		}
+
+		/**
+		* Constructor from Asn1Sequence.
+		* <p/>
+		* The sequence is of type ProcurationSyntax:
+		* <p/>
+		* <pre>
+		*            Admissions ::= SEQUENCE
+		*            {
+		*              admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
+		*              namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
+		*              professionInfos SEQUENCE OF ProfessionInfo
+		*            }
+		* </pre>
+		*
+		* @param seq The ASN.1 sequence.
+		*/
+		private Admissions(
+			Asn1Sequence seq)
+		{
+			if (seq.Count > 3)
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+			IEnumerator e = seq.GetEnumerator();
+
+			e.MoveNext();
+			Asn1Encodable o = (Asn1Encodable) e.Current;
+			if (o is Asn1TaggedObject)
+			{
+				switch (((Asn1TaggedObject)o).TagNo)
+				{
+					case 0:
+						admissionAuthority = GeneralName.GetInstance((Asn1TaggedObject)o, true);
+						break;
+					case 1:
+						namingAuthority = NamingAuthority.GetInstance((Asn1TaggedObject)o, true);
+						break;
+					default:
+						throw new ArgumentException("Bad tag number: " + ((Asn1TaggedObject)o).TagNo);
+				}
+				e.MoveNext();
+				o = (Asn1Encodable) e.Current;
+			}
+			if (o is Asn1TaggedObject)
+			{
+				switch (((Asn1TaggedObject)o).TagNo)
+				{
+					case 1:
+						namingAuthority = NamingAuthority.GetInstance((Asn1TaggedObject)o, true);
+						break;
+					default:
+						throw new ArgumentException("Bad tag number: " + ((Asn1TaggedObject)o).TagNo);
+				}
+				e.MoveNext();
+				o = (Asn1Encodable) e.Current;
+			}
+			professionInfos = Asn1Sequence.GetInstance(o);
+			if (e.MoveNext())
+			{
+				throw new ArgumentException("Bad object encountered: " + e.Current.GetType().Name);
+			}
+		}
+
+		/**
+		* Constructor from a given details.
+		* <p/>
+		* Parameter <code>professionInfos</code> is mandatory.
+		*
+		* @param admissionAuthority The admission authority.
+		* @param namingAuthority    The naming authority.
+		* @param professionInfos    The profession infos.
+		*/
+		public Admissions(
+			GeneralName			admissionAuthority,
+			NamingAuthority		namingAuthority,
+			ProfessionInfo[]	professionInfos)
+		{
+			this.admissionAuthority = admissionAuthority;
+			this.namingAuthority = namingAuthority;
+			this.professionInfos = new DerSequence(professionInfos);
+		}
+
+		public virtual GeneralName AdmissionAuthority
+		{
+			get { return admissionAuthority; }
+		}
+
+		public virtual NamingAuthority NamingAuthority
+		{
+			get { return namingAuthority; }
+		}
+
+		public ProfessionInfo[] GetProfessionInfos()
+		{
+			ProfessionInfo[] infos = new ProfessionInfo[professionInfos.Count];
+			int count = 0;
+			foreach (Asn1Encodable ae in professionInfos)
+			{
+				infos[count++] = ProfessionInfo.GetInstance(ae);
+			}
+			return infos;
+		}
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*       Admissions ::= SEQUENCE
+		*       {
+		*         admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
+		*         namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
+		*         professionInfos SEQUENCE OF ProfessionInfo
+		*       }
+		* <p/>
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector vec = new Asn1EncodableVector();
+
+			if (admissionAuthority != null)
+			{
+				vec.Add(new DerTaggedObject(true, 0, admissionAuthority));
+			}
+
+			if (namingAuthority != null)
+			{
+				vec.Add(new DerTaggedObject(true, 1, namingAuthority));
+			}
+
+			vec.Add(professionInfos);
+
+			return new DerSequence(vec);
+		}
+	}
+}
diff --git a/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs
new file mode 100644
index 000000000..dfac65040
--- /dev/null
+++ b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs
@@ -0,0 +1,170 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+	/**
+	* A declaration of majority.
+	* <p/>
+	* <pre>
+	*           DeclarationOfMajoritySyntax ::= CHOICE
+	*           {
+	*             notYoungerThan [0] IMPLICIT INTEGER,
+	*             fullAgeAtCountry [1] IMPLICIT SEQUENCE
+	*             {
+	*               fullAge BOOLEAN DEFAULT TRUE,
+	*               country PrintableString (SIZE(2))
+	*             }
+	*             dateOfBirth [2] IMPLICIT GeneralizedTime
+	*           }
+	* </pre>
+	* <p/>
+	* fullAgeAtCountry indicates the majority of the owner with respect to the laws
+	* of a specific country.
+	*/
+	public class DeclarationOfMajority
+		: Asn1Encodable, IAsn1Choice
+	{
+		public enum Choice
+		{
+			NotYoungerThan = 0,
+			FullAgeAtCountry = 1,
+			DateOfBirth = 2
+		};
+
+		private readonly Asn1TaggedObject declaration;
+
+		public DeclarationOfMajority(
+			int notYoungerThan)
+		{
+			declaration = new DerTaggedObject(false, 0, new DerInteger(notYoungerThan));
+		}
+
+		public DeclarationOfMajority(
+			bool	fullAge,
+			string	country)
+		{
+			if (country.Length > 2)
+				throw new ArgumentException("country can only be 2 characters");
+
+			DerPrintableString countryString = new DerPrintableString(country, true);
+
+			DerSequence seq;
+			if (fullAge)
+			{
+				seq = new DerSequence(countryString);
+			}
+			else
+			{
+				seq = new DerSequence(DerBoolean.False, countryString);
+			}
+
+			this.declaration = new DerTaggedObject(false, 1, seq);
+		}
+
+		public DeclarationOfMajority(
+			DerGeneralizedTime dateOfBirth)
+		{
+			this.declaration = new DerTaggedObject(false, 2, dateOfBirth);
+		}
+
+		public static DeclarationOfMajority GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is DeclarationOfMajority)
+			{
+				return (DeclarationOfMajority) obj;
+			}
+
+			if (obj is Asn1TaggedObject)
+			{
+				return new DeclarationOfMajority((Asn1TaggedObject) obj);
+			}
+
+			throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+		}
+
+		private DeclarationOfMajority(
+			Asn1TaggedObject o)
+		{
+			if (o.TagNo > 2)
+				throw new ArgumentException("Bad tag number: " + o.TagNo);
+
+			this.declaration = o;
+		}
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*           DeclarationOfMajoritySyntax ::= CHOICE
+		*           {
+		*             notYoungerThan [0] IMPLICIT INTEGER,
+		*             fullAgeAtCountry [1] IMPLICIT SEQUENCE
+		*             {
+		*               fullAge BOOLEAN DEFAULT TRUE,
+		*               country PrintableString (SIZE(2))
+		*             }
+		*             dateOfBirth [2] IMPLICIT GeneralizedTime
+		*           }
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			return declaration;
+		}
+
+		public Choice Type
+		{
+			get { return (Choice) declaration.TagNo; }
+		}
+
+		/**
+		* @return notYoungerThan if that's what we are, -1 otherwise
+		*/
+		public virtual int NotYoungerThan
+		{
+			get
+			{
+				switch ((Choice) declaration.TagNo)
+				{
+					case Choice.NotYoungerThan:
+						return DerInteger.GetInstance(declaration, false).Value.IntValue;
+					default:
+						return -1;
+				}
+			}
+		}
+
+		public virtual Asn1Sequence FullAgeAtCountry
+		{
+			get
+			{
+				switch ((Choice) declaration.TagNo)
+				{
+					case Choice.FullAgeAtCountry:
+						return Asn1Sequence.GetInstance(declaration, false);
+					default:
+						return null;
+				}
+			}
+		}
+
+		public virtual DerGeneralizedTime DateOfBirth
+		{
+			get
+			{
+				switch ((Choice) declaration.TagNo)
+				{
+					case Choice.DateOfBirth:
+						return DerGeneralizedTime.GetInstance(declaration, false);
+					default:
+						return null;
+				}
+			}
+		}
+	}
+}
diff --git a/crypto/src/asn1/isismtt/x509/MonetaryLimit.cs b/crypto/src/asn1/isismtt/x509/MonetaryLimit.cs
new file mode 100644
index 000000000..80b6b684b
--- /dev/null
+++ b/crypto/src/asn1/isismtt/x509/MonetaryLimit.cs
@@ -0,0 +1,121 @@
+using System;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+	/**
+	* Monetary limit for transactions. The QcEuMonetaryLimit QC statement MUST be
+	* used in new certificates in place of the extension/attribute MonetaryLimit
+	* since January 1, 2004. For the sake of backward compatibility with
+	* certificates already in use, components SHOULD support MonetaryLimit (as well
+	* as QcEuLimitValue).
+	* <p/>
+	* Indicates a monetary limit within which the certificate holder is authorized
+	* to act. (This value DOES NOT express a limit on the liability of the
+	* certification authority).
+	* <p/>
+	* <pre>
+	*    MonetaryLimitSyntax ::= SEQUENCE
+	*    {
+	*      currency PrintableString (SIZE(3)),
+	*      amount INTEGER,
+	*      exponent INTEGER
+	*    }
+	* </pre>
+	* <p/>
+	* currency must be the ISO code.
+	* <p/>
+	* value = amount�10*exponent
+	*/
+	public class MonetaryLimit
+		: Asn1Encodable
+	{
+		private readonly DerPrintableString	currency;
+		private readonly DerInteger			amount;
+		private readonly DerInteger			exponent;
+
+		public static MonetaryLimit GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is MonetaryLimit)
+			{
+				return (MonetaryLimit) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new MonetaryLimit(Asn1Sequence.GetInstance(obj));
+			}
+
+			throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+		}
+
+		private MonetaryLimit(
+			Asn1Sequence seq)
+		{
+			if (seq.Count != 3)
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+			currency = DerPrintableString.GetInstance(seq[0]);
+			amount = DerInteger.GetInstance(seq[1]);
+			exponent = DerInteger.GetInstance(seq[2]);
+		}
+
+		/**
+		* Constructor from a given details.
+		* <p/>
+		* <p/>
+		* value = amount�10^exponent
+		*
+		* @param currency The currency. Must be the ISO code.
+		* @param amount   The amount
+		* @param exponent The exponent
+		*/
+		public MonetaryLimit(
+			string	currency,
+			int		amount,
+			int		exponent)
+		{
+			this.currency = new DerPrintableString(currency, true);
+			this.amount = new DerInteger(amount);
+			this.exponent = new DerInteger(exponent);
+		}
+
+		public virtual string Currency
+		{
+			get { return currency.GetString(); }
+		}
+
+		public virtual BigInteger Amount
+		{
+			get { return amount.Value; }
+		}
+
+		public virtual BigInteger Exponent
+		{
+			get { return exponent.Value; }
+		}
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*    MonetaryLimitSyntax ::= SEQUENCE
+		*    {
+		*      currency PrintableString (SIZE(3)),
+		*      amount INTEGER,
+		*      exponent INTEGER
+		*    }
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			return new DerSequence(currency, amount, exponent);
+		}
+	}
+}
diff --git a/crypto/src/asn1/isismtt/x509/NamingAuthority.cs b/crypto/src/asn1/isismtt/x509/NamingAuthority.cs
new file mode 100644
index 000000000..4262fd0f4
--- /dev/null
+++ b/crypto/src/asn1/isismtt/x509/NamingAuthority.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+	/**
+	* Names of authorities which are responsible for the administration of title
+	* registers.
+	* 
+	* <pre>
+	*             NamingAuthority ::= SEQUENCE 
+	*             {
+	*               namingAuthorityID OBJECT IDENTIFIER OPTIONAL,
+	*               namingAuthorityUrl IA5String OPTIONAL,
+	*               namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
+	*             }
+	* </pre>
+	* @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdmissionSyntax
+	* 
+	*/
+	public class NamingAuthority
+		: Asn1Encodable
+	{
+		/**
+		* Profession OIDs should always be defined under the OID branch of the
+		* responsible naming authority. At the time of this writing, the work group
+		* �Recht, Wirtschaft, Steuern� (�Law, Economy, Taxes�) is registered as the
+		* first naming authority under the OID id-isismtt-at-namingAuthorities.
+		*/
+		public static readonly DerObjectIdentifier IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern
+			= new DerObjectIdentifier(IsisMttObjectIdentifiers.IdIsisMttATNamingAuthorities + ".1");
+
+		private readonly DerObjectIdentifier	namingAuthorityID;
+		private readonly string					namingAuthorityUrl;
+		private readonly DirectoryString		namingAuthorityText;
+
+		public static NamingAuthority GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is NamingAuthority)
+			{
+				return (NamingAuthority) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new NamingAuthority((Asn1Sequence) obj);
+			}
+
+			throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+		}
+
+		public static NamingAuthority GetInstance(
+			Asn1TaggedObject	obj,
+			bool				isExplicit)
+		{
+			return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+		}
+
+		/**
+		* Constructor from Asn1Sequence.
+		* <p/>
+		* <p/>
+		* <pre>
+		*             NamingAuthority ::= SEQUENCE
+		*             {
+		*               namingAuthorityID OBJECT IDENTIFIER OPTIONAL,
+		*               namingAuthorityUrl IA5String OPTIONAL,
+		*               namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
+		*             }
+		* </pre>
+		*
+		* @param seq The ASN.1 sequence.
+		*/
+		private NamingAuthority(
+			Asn1Sequence seq)
+		{
+			if (seq.Count > 3)
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+			IEnumerator e = seq.GetEnumerator();
+
+			if (e.MoveNext())
+			{
+				Asn1Encodable o = (Asn1Encodable) e.Current;
+				if (o is DerObjectIdentifier)
+				{
+					namingAuthorityID = (DerObjectIdentifier) o;
+				}
+				else if (o is DerIA5String)
+				{
+					namingAuthorityUrl = DerIA5String.GetInstance(o).GetString();
+				}
+				else if (o is IAsn1String)
+				{
+					namingAuthorityText = DirectoryString.GetInstance(o);
+				}
+				else
+				{
+					throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+				}
+			}
+
+			if (e.MoveNext())
+			{
+				Asn1Encodable o = (Asn1Encodable) e.Current;
+				if (o is DerIA5String)
+				{
+					namingAuthorityUrl = DerIA5String.GetInstance(o).GetString();
+				}
+				else if (o is IAsn1String)
+				{
+					namingAuthorityText = DirectoryString.GetInstance(o);
+				}
+				else
+				{
+					throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+				}
+			}
+
+			if (e.MoveNext())
+			{
+				Asn1Encodable o = (Asn1Encodable) e.Current;
+				if (o is IAsn1String)
+				{
+					namingAuthorityText = DirectoryString.GetInstance(o);
+				}
+				else
+				{
+					throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+				}
+			}
+		}
+
+		/**
+		* @return Returns the namingAuthorityID.
+		*/
+		public virtual DerObjectIdentifier NamingAuthorityID
+		{
+			get { return namingAuthorityID; }
+		}
+
+		/**
+		* @return Returns the namingAuthorityText.
+		*/
+		public virtual DirectoryString NamingAuthorityText
+		{
+			get { return namingAuthorityText; }
+		}
+
+		/**
+		* @return Returns the namingAuthorityUrl.
+		*/
+		public virtual string NamingAuthorityUrl
+		{
+			get { return namingAuthorityUrl; }
+		}
+
+		/**
+		* Constructor from given details.
+		* <p/>
+		* All parameters can be combined.
+		*
+		* @param namingAuthorityID   ObjectIdentifier for naming authority.
+		* @param namingAuthorityUrl  URL for naming authority.
+		* @param namingAuthorityText Textual representation of naming authority.
+		*/
+		public NamingAuthority(
+			DerObjectIdentifier	namingAuthorityID,
+			string				namingAuthorityUrl,
+			DirectoryString		namingAuthorityText)
+		{
+			this.namingAuthorityID = namingAuthorityID;
+			this.namingAuthorityUrl = namingAuthorityUrl;
+			this.namingAuthorityText = namingAuthorityText;
+		}
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*             NamingAuthority ::= SEQUENCE
+		*             {
+		*               namingAuthorityID OBJECT IDENTIFIER OPTIONAL,
+		*               namingAuthorityUrl IA5String OPTIONAL,
+		*               namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
+		*             }
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector vec = new Asn1EncodableVector();
+			if (namingAuthorityID != null)
+			{
+				vec.Add(namingAuthorityID);
+			}
+			if (namingAuthorityUrl != null)
+			{
+				vec.Add(new DerIA5String(namingAuthorityUrl, true));
+			}
+			if (namingAuthorityText != null)
+			{
+				vec.Add(namingAuthorityText);
+			}
+			return new DerSequence(vec);
+		}
+	}
+}
diff --git a/crypto/src/asn1/isismtt/x509/ProcurationSyntax.cs b/crypto/src/asn1/isismtt/x509/ProcurationSyntax.cs
new file mode 100644
index 000000000..a25df225e
--- /dev/null
+++ b/crypto/src/asn1/isismtt/x509/ProcurationSyntax.cs
@@ -0,0 +1,232 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X500;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+	/**
+	* Attribute to indicate that the certificate holder may sign in the name of a
+	* third person.
+	* <p>
+	* ISIS-MTT PROFILE: The corresponding ProcurationSyntax contains either the
+	* name of the person who is represented (subcomponent thirdPerson) or a
+	* reference to his/her base certificate (in the component signingFor,
+	* subcomponent certRef), furthermore the optional components country and
+	* typeSubstitution to indicate the country whose laws apply, and respectively
+	* the type of procuration (e.g. manager, procuration, custody).
+	* </p>
+	* <p>
+	* ISIS-MTT PROFILE: The GeneralName MUST be of type directoryName and MAY only
+	* contain: - RFC3039 attributes, except pseudonym (countryName, commonName,
+	* surname, givenName, serialNumber, organizationName, organizationalUnitName,
+	* stateOrProvincename, localityName, postalAddress) and - SubjectDirectoryName
+	* attributes (title, dateOfBirth, placeOfBirth, gender, countryOfCitizenship,
+	* countryOfResidence and NameAtBirth).
+	* </p>
+	* <pre>
+	*               ProcurationSyntax ::= SEQUENCE {
+	*                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
+	*                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
+	*                 signingFor [3] EXPLICIT SigningFor 
+	*               }
+	*               
+	*               SigningFor ::= CHOICE 
+	*               { 
+	*                 thirdPerson GeneralName,
+	*                 certRef IssuerSerial 
+	*               }
+	* </pre>
+	* 
+	*/
+	public class ProcurationSyntax
+		: Asn1Encodable
+	{
+		private readonly string				country;
+		private readonly DirectoryString	typeOfSubstitution;
+		private readonly GeneralName		thirdPerson;
+		private readonly IssuerSerial		certRef;
+
+		public static ProcurationSyntax GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is ProcurationSyntax)
+			{
+				return (ProcurationSyntax) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new ProcurationSyntax((Asn1Sequence) obj);
+			}
+
+			throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+		}
+
+		/**
+		* Constructor from Asn1Sequence.
+		* <p/>
+		* The sequence is of type ProcurationSyntax:
+		* <p/>
+		* <pre>
+		*               ProcurationSyntax ::= SEQUENCE {
+		*                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
+		*                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
+		*                 signingFor [3] EXPLICIT SigningFor
+		*               }
+		* <p/>
+		*               SigningFor ::= CHOICE
+		*               {
+		*                 thirdPerson GeneralName,
+		*                 certRef IssuerSerial
+		*               }
+		* </pre>
+		*
+		* @param seq The ASN.1 sequence.
+		*/
+		private ProcurationSyntax(
+			Asn1Sequence seq)
+		{
+			if (seq.Count < 1 || seq.Count > 3)
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+			IEnumerator e = seq.GetEnumerator();
+
+			while (e.MoveNext())
+			{
+				Asn1TaggedObject o = Asn1TaggedObject.GetInstance(e.Current);
+				switch (o.TagNo)
+				{
+					case 1:
+						country = DerPrintableString.GetInstance(o, true).GetString();
+						break;
+					case 2:
+						typeOfSubstitution = DirectoryString.GetInstance(o, true);
+						break;
+					case 3:
+						Asn1Object signingFor = o.GetObject();
+						if (signingFor is Asn1TaggedObject)
+						{
+							thirdPerson = GeneralName.GetInstance(signingFor);
+						}
+						else
+						{
+							certRef = IssuerSerial.GetInstance(signingFor);
+						}
+						break;
+					default:
+						throw new ArgumentException("Bad tag number: " + o.TagNo);
+				}
+			}
+		}
+
+		/**
+		* Constructor from a given details.
+		* <p/>
+		* <p/>
+		* Either <code>generalName</code> or <code>certRef</code> MUST be
+		* <code>null</code>.
+		*
+		* @param country            The country code whose laws apply.
+		* @param typeOfSubstitution The type of procuration.
+		* @param certRef            Reference to certificate of the person who is represented.
+		*/
+		public ProcurationSyntax(
+			string			country,
+			DirectoryString	typeOfSubstitution,
+			IssuerSerial	certRef)
+		{
+			this.country = country;
+			this.typeOfSubstitution = typeOfSubstitution;
+			this.thirdPerson = null;
+			this.certRef = certRef;
+		}
+
+		/**
+		 * Constructor from a given details.
+		 * <p/>
+		 * <p/>
+		 * Either <code>generalName</code> or <code>certRef</code> MUST be
+		 * <code>null</code>.
+		 *
+		 * @param country            The country code whose laws apply.
+		 * @param typeOfSubstitution The type of procuration.
+		 * @param thirdPerson        The GeneralName of the person who is represented.
+		 */
+		public ProcurationSyntax(
+			string			country,
+			DirectoryString	typeOfSubstitution,
+			GeneralName		thirdPerson)
+		{
+			this.country = country;
+			this.typeOfSubstitution = typeOfSubstitution;
+			this.thirdPerson = thirdPerson;
+			this.certRef = null;
+		}
+
+		public virtual string Country
+		{
+			get { return country; }
+		}
+
+		public virtual DirectoryString TypeOfSubstitution
+		{
+			get { return typeOfSubstitution; }
+		}
+
+		public virtual GeneralName ThirdPerson
+		{
+			get { return thirdPerson; }
+		}
+
+		public virtual IssuerSerial CertRef
+		{
+			get { return certRef; }
+		}
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*               ProcurationSyntax ::= SEQUENCE {
+		*                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
+		*                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
+		*                 signingFor [3] EXPLICIT SigningFor
+		*               }
+		* <p/>
+		*               SigningFor ::= CHOICE
+		*               {
+		*                 thirdPerson GeneralName,
+		*                 certRef IssuerSerial
+		*               }
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector vec = new Asn1EncodableVector();
+			if (country != null)
+			{
+				vec.Add(new DerTaggedObject(true, 1, new DerPrintableString(country, true)));
+			}
+			if (typeOfSubstitution != null)
+			{
+				vec.Add(new DerTaggedObject(true, 2, typeOfSubstitution));
+			}
+			if (thirdPerson != null)
+			{
+				vec.Add(new DerTaggedObject(true, 3, thirdPerson));
+			}
+			else
+			{
+				vec.Add(new DerTaggedObject(true, 3, certRef));
+			}
+
+			return new DerSequence(vec);
+		}
+	}
+}
diff --git a/crypto/src/asn1/isismtt/x509/ProfessionInfo.cs b/crypto/src/asn1/isismtt/x509/ProfessionInfo.cs
new file mode 100644
index 000000000..3bad2cbc4
--- /dev/null
+++ b/crypto/src/asn1/isismtt/x509/ProfessionInfo.cs
@@ -0,0 +1,386 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+	/**
+	* Professions, specializations, disciplines, fields of activity, etc.
+	* 
+	* <pre>
+	*               ProfessionInfo ::= SEQUENCE 
+	*               {
+	*                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
+	*                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
+	*                 professionOids SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+	*                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
+	*                 addProfessionInfo OCTET STRING OPTIONAL 
+	*               }
+	* </pre>
+	* 
+	* @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdmissionSyntax
+	*/
+	public class ProfessionInfo
+		: Asn1Encodable
+	{
+		/**
+		* Rechtsanw�ltin
+		*/
+		public static readonly DerObjectIdentifier Rechtsanwltin = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".1");
+
+		/**
+		* Rechtsanwalt
+		*/
+		public static readonly DerObjectIdentifier Rechtsanwalt = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".2");
+
+		/**
+		* Rechtsbeistand
+		*/
+		public static readonly DerObjectIdentifier Rechtsbeistand = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".3");
+
+		/**
+		* Steuerberaterin
+		*/
+		public static readonly DerObjectIdentifier Steuerberaterin = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".4");
+
+		/**
+		* Steuerberater
+		*/
+		public static readonly DerObjectIdentifier Steuerberater = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".5");
+
+		/**
+		* Steuerbevollm�chtigte
+		*/
+		public static readonly DerObjectIdentifier Steuerbevollmchtigte = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".6");
+
+		/**
+		* Steuerbevollm�chtigter
+		*/
+		public static readonly DerObjectIdentifier Steuerbevollmchtigter = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".7");
+
+		/**
+		* Notarin
+		*/
+		public static readonly DerObjectIdentifier Notarin = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".8");
+
+		/**
+		* Notar
+		*/
+		public static readonly DerObjectIdentifier Notar = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".9");
+
+		/**
+		* Notarvertreterin
+		*/
+		public static readonly DerObjectIdentifier Notarvertreterin = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".10");
+
+		/**
+		* Notarvertreter
+		*/
+		public static readonly DerObjectIdentifier Notarvertreter = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".11");
+
+		/**
+		* Notariatsverwalterin
+		*/
+		public static readonly DerObjectIdentifier Notariatsverwalterin = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".12");
+
+		/**
+		* Notariatsverwalter
+		*/
+		public static readonly DerObjectIdentifier Notariatsverwalter = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".13");
+
+		/**
+		* Wirtschaftspr�ferin
+		*/
+		public static readonly DerObjectIdentifier Wirtschaftsprferin = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".14");
+
+		/**
+		* Wirtschaftspr�fer
+		*/
+		public static readonly DerObjectIdentifier Wirtschaftsprfer = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".15");
+
+		/**
+		* Vereidigte Buchpr�ferin
+		*/
+		public static readonly DerObjectIdentifier VereidigteBuchprferin = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".16");
+
+		/**
+		* Vereidigter Buchpr�fer
+		*/
+		public static readonly DerObjectIdentifier VereidigterBuchprfer = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".17");
+
+		/**
+		* Patentanw�ltin
+		*/
+		public static readonly DerObjectIdentifier Patentanwltin = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".18");
+
+		/**
+		* Patentanwalt
+		*/
+		public static readonly DerObjectIdentifier Patentanwalt = new DerObjectIdentifier(
+			NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".19");
+
+		private readonly NamingAuthority	namingAuthority;
+		private readonly Asn1Sequence		professionItems;
+		private readonly Asn1Sequence		professionOids;
+		private readonly string				registrationNumber;
+		private readonly Asn1OctetString	addProfessionInfo;
+
+		public static ProfessionInfo GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is ProfessionInfo)
+			{
+				return (ProfessionInfo) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new ProfessionInfo((Asn1Sequence) obj);
+			}
+
+			throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+		}
+
+		/**
+		* Constructor from Asn1Sequence.
+		* <p/>
+		* <p/>
+		* <pre>
+		*               ProfessionInfo ::= SEQUENCE
+		*               {
+		*                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
+		*                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
+		*                 professionOids SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+		*                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
+		*                 addProfessionInfo OCTET STRING OPTIONAL
+		*               }
+		* </pre>
+		*
+		* @param seq The ASN.1 sequence.
+		*/
+		private ProfessionInfo(
+			Asn1Sequence seq)
+		{
+			if (seq.Count > 5)
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+
+			IEnumerator e = seq.GetEnumerator();
+
+			e.MoveNext();
+			Asn1Encodable o = (Asn1Encodable) e.Current;
+
+			if (o is Asn1TaggedObject)
+			{
+				Asn1TaggedObject ato = (Asn1TaggedObject) o;
+				if (ato.TagNo != 0)
+					throw new ArgumentException("Bad tag number: " + ato.TagNo);
+
+				namingAuthority = NamingAuthority.GetInstance(ato, true);
+				e.MoveNext();
+				o = (Asn1Encodable) e.Current;
+			}
+
+			professionItems = Asn1Sequence.GetInstance(o);
+
+			if (e.MoveNext())
+			{
+				o = (Asn1Encodable) e.Current;
+				if (o is Asn1Sequence)
+				{
+					professionOids = Asn1Sequence.GetInstance(o);
+				}
+				else if (o is DerPrintableString)
+				{
+					registrationNumber = DerPrintableString.GetInstance(o).GetString();
+				}
+				else if (o is Asn1OctetString)
+				{
+					addProfessionInfo = Asn1OctetString.GetInstance(o);
+				}
+				else
+				{
+					throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+				}
+			}
+
+			if (e.MoveNext())
+			{
+				o = (Asn1Encodable) e.Current;
+				if (o is DerPrintableString)
+				{
+					registrationNumber = DerPrintableString.GetInstance(o).GetString();
+				}
+				else if (o is DerOctetString)
+				{
+					addProfessionInfo = (DerOctetString) o;
+				}
+				else
+				{
+					throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+				}
+			}
+
+			if (e.MoveNext())
+			{
+				o = (Asn1Encodable) e.Current;
+				if (o is DerOctetString)
+				{
+					addProfessionInfo = (DerOctetString) o;
+				}
+				else
+				{
+					throw new ArgumentException("Bad object encountered: " + o.GetType().Name);
+				}
+			}
+		}
+
+		/**
+		* Constructor from given details.
+		* <p/>
+		* <code>professionItems</code> is mandatory, all other parameters are
+		* optional.
+		*
+		* @param namingAuthority    The naming authority.
+		* @param professionItems    Directory strings of the profession.
+		* @param professionOids     DERObjectIdentfier objects for the
+		*                           profession.
+		* @param registrationNumber Registration number.
+		* @param addProfessionInfo  Additional infos in encoded form.
+		*/
+		public ProfessionInfo(
+			NamingAuthority			namingAuthority,
+			DirectoryString[]		professionItems,
+			DerObjectIdentifier[]	professionOids,
+			string					registrationNumber,
+			Asn1OctetString			addProfessionInfo)
+		{
+			this.namingAuthority = namingAuthority;
+			this.professionItems = new DerSequence(professionItems);
+			if (professionOids != null)
+			{
+				this.professionOids = new DerSequence(professionOids);
+			}
+			this.registrationNumber = registrationNumber;
+			this.addProfessionInfo = addProfessionInfo;
+		}
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*               ProfessionInfo ::= SEQUENCE
+		*               {
+		*                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
+		*                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
+		*                 professionOids SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+		*                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
+		*                 addProfessionInfo OCTET STRING OPTIONAL
+		*               }
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector vec = new Asn1EncodableVector();
+			if (namingAuthority != null)
+			{
+				vec.Add(new DerTaggedObject(true, 0, namingAuthority));
+			}
+			vec.Add(professionItems);
+			if (professionOids != null)
+			{
+				vec.Add(professionOids);
+			}
+			if (registrationNumber != null)
+			{
+				vec.Add(new DerPrintableString(registrationNumber, true));
+			}
+			if (addProfessionInfo != null)
+			{
+				vec.Add(addProfessionInfo);
+			}
+			return new DerSequence(vec);
+		}
+
+		/**
+		* @return Returns the addProfessionInfo.
+		*/
+		public virtual Asn1OctetString AddProfessionInfo
+		{
+			get { return addProfessionInfo; }
+		}
+
+		/**
+		* @return Returns the namingAuthority.
+		*/
+		public virtual NamingAuthority NamingAuthority
+		{
+			get { return namingAuthority; }
+		}
+
+		/**
+		* @return Returns the professionItems.
+		*/
+		public virtual DirectoryString[] GetProfessionItems()
+		{
+			DirectoryString[] result = new DirectoryString[professionItems.Count];
+
+			for (int i = 0; i < professionItems.Count; ++i)
+			{
+				result[i] = DirectoryString.GetInstance(professionItems[i]);
+			}
+
+			return result;
+		}
+
+		/**
+		* @return Returns the professionOids.
+		*/
+		public virtual DerObjectIdentifier[] GetProfessionOids()
+		{
+			if (professionOids == null)
+			{
+				return new DerObjectIdentifier[0];
+			}
+
+			DerObjectIdentifier[] result = new DerObjectIdentifier[professionOids.Count];
+
+			for (int i = 0; i < professionOids.Count; ++i)
+			{
+				result[i] = DerObjectIdentifier.GetInstance(professionOids[i]);
+			}
+
+			return result;
+		}
+
+		/**
+		* @return Returns the registrationNumber.
+		*/
+		public virtual string RegistrationNumber
+		{
+			get { return registrationNumber; }
+		}
+	}
+}
diff --git a/crypto/src/asn1/isismtt/x509/Restriction.cs b/crypto/src/asn1/isismtt/x509/Restriction.cs
new file mode 100644
index 000000000..c97766999
--- /dev/null
+++ b/crypto/src/asn1/isismtt/x509/Restriction.cs
@@ -0,0 +1,81 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.IsisMtt.X509
+{
+	/**
+	* Some other restriction regarding the usage of this certificate.
+	* <p/>
+	* <pre>
+	*  RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+	* </pre>
+	*/
+	public class Restriction
+		: Asn1Encodable
+	{
+		private readonly DirectoryString restriction;
+
+		public static Restriction GetInstance(
+			object obj)
+		{
+			if (obj is Restriction)
+				return (Restriction) obj;
+
+			if (obj is IAsn1String)
+				return new Restriction(DirectoryString.GetInstance(obj));
+
+			throw new ArgumentException("Unknown object in GetInstance: " + obj.GetType().Name, "obj");
+		}
+
+		/**
+		* Constructor from DirectoryString.
+		* <p/>
+		* The DirectoryString is of type RestrictionSyntax:
+		* <p/>
+		* <pre>
+		*      RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+		* </pre>
+		*
+		* @param restriction A IAsn1String.
+		*/
+		private Restriction(
+			DirectoryString restriction)
+		{
+			this.restriction = restriction;
+		}
+
+		/**
+		* Constructor from a given details.
+		*
+		* @param restriction The description of the restriction.
+		*/
+		public Restriction(
+			string restriction)
+		{
+			this.restriction = new DirectoryString(restriction);
+		}
+
+		public virtual DirectoryString RestrictionString
+		{
+			get { return restriction; }
+		}
+
+		/**
+		* Produce an object suitable for an Asn1OutputStream.
+		* <p/>
+		* Returns:
+		* <p/>
+		* <pre>
+		*      RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+		* <p/>
+		* </pre>
+		*
+		* @return an Asn1Object
+		*/
+		public override Asn1Object ToAsn1Object()
+		{
+			return restriction.ToAsn1Object();
+		}
+	}
+}