summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto-test/crypto-test.csproj199
-rw-r--r--crypto/crypto.csproj2
-rw-r--r--crypto/src/asn1/x509/X509ExtensionsGenerator.cs195
-rw-r--r--crypto/src/pkcs/Pkcs10CertificationRequest.cs583
-rw-r--r--crypto/test/src/asn1/test/X509ExtensionsTest.cs322
-rw-r--r--crypto/test/src/test/PKCS10CertRequestTest.cs222
-rw-r--r--csharp.sln39
7 files changed, 938 insertions, 624 deletions
diff --git a/crypto-test/crypto-test.csproj b/crypto-test/crypto-test.csproj
index 9bb4cdbb9..50c293aff 100644
--- a/crypto-test/crypto-test.csproj
+++ b/crypto-test/crypto-test.csproj
@@ -1,104 +1,95 @@
-<VisualStudioProject>
-    <CSHARP
-        ProjectType = "Local"
-        ProductVersion = "7.10.3077"
-        SchemaVersion = "2.0"
-        ProjectGuid = "{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}"
-    >
-        <Build>
-            <Settings
-                ApplicationIcon = "App.ico"
-                AssemblyKeyContainerName = ""
-                AssemblyName = "crypto-test"
-                AssemblyOriginatorKeyFile = ""
-                DefaultClientScript = "JScript"
-                DefaultHTMLPageLayout = "Grid"
-                DefaultTargetSchema = "IE50"
-                DelaySign = "false"
-                OutputType = "Exe"
-                PreBuildEvent = ""
-                PostBuildEvent = ""
-                RootNamespace = "crypto_test"
-                RunPostBuildEvent = "OnBuildSuccess"
-                StartupObject = ""
-            >
-                <Config
-                    Name = "Debug"
-                    AllowUnsafeBlocks = "false"
-                    BaseAddress = "285212672"
-                    CheckForOverflowUnderflow = "false"
-                    ConfigurationOverrideFile = ""
-                    DefineConstants = "DEBUG;TRACE"
-                    DocumentationFile = ""
-                    DebugSymbols = "true"
-                    FileAlignment = "4096"
-                    IncrementalBuild = "false"
-                    NoStdLib = "false"
-                    NoWarn = ""
-                    Optimize = "false"
-                    OutputPath = "bin\Debug\"
-                    RegisterForComInterop = "false"
-                    RemoveIntegerChecks = "false"
-                    TreatWarningsAsErrors = "false"
-                    WarningLevel = "4"
-                />
-                <Config
-                    Name = "Release"
-                    AllowUnsafeBlocks = "false"
-                    BaseAddress = "285212672"
-                    CheckForOverflowUnderflow = "false"
-                    ConfigurationOverrideFile = ""
-                    DefineConstants = "TRACE"
-                    DocumentationFile = ""
-                    DebugSymbols = "false"
-                    FileAlignment = "4096"
-                    IncrementalBuild = "false"
-                    NoStdLib = "false"
-                    NoWarn = ""
-                    Optimize = "true"
-                    OutputPath = "bin\Release\"
-                    RegisterForComInterop = "false"
-                    RemoveIntegerChecks = "false"
-                    TreatWarningsAsErrors = "false"
-                    WarningLevel = "4"
-                />
-            </Settings>
-            <References>
-                <Reference
-                    Name = "System"
-                    AssemblyName = "System"
-                    HintPath = "..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
-                />
-                <Reference
-                    Name = "System.Data"
-                    AssemblyName = "System.Data"
-                    HintPath = "..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
-                />
-                <Reference
-                    Name = "System.XML"
-                    AssemblyName = "System.Xml"
-                    HintPath = "..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
-                />
-                <Reference
-                    Name = "crypto"
-                    Project = "{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}"
-                    Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
-                />
-            </References>
-        </Build>
-        <Files>
-            <Include>
-                <File
-                    RelPath = "App.ico"
-                    BuildAction = "Content"
-                />
-                <File
-                    RelPath = "CryptoTest.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-            </Include>
-        </Files>
-    </CSHARP>
-</VisualStudioProject>
-
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
+  <PropertyGroup>
+    <ProjectType>Local</ProjectType>
+    <ProductVersion>7.10.3077</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ApplicationIcon>App.ico</ApplicationIcon>
+    <AssemblyKeyContainerName />
+    <AssemblyName>crypto-test</AssemblyName>
+    <AssemblyOriginatorKeyFile />
+    <DefaultClientScript>JScript</DefaultClientScript>
+    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+    <DefaultTargetSchema>IE50</DefaultTargetSchema>
+    <DelaySign>false</DelaySign>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>crypto_test</RootNamespace>
+    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+    <StartupObject />
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>0.0</OldToolsVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <OutputPath>bin\Debug\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile />
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DocumentationFile />
+    <DebugSymbols>true</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn />
+    <Optimize>false</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>full</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <OutputPath>bin\Release\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile />
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile />
+    <DebugSymbols>false</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn />
+    <Optimize>true</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>none</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\crypto\crypto.csproj">
+      <Name>crypto</Name>
+      <Project>{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}</Project>
+      <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
+    </ProjectReference>
+    <Reference Include="System">
+      <Name>System</Name>
+    </Reference>
+    <Reference Include="System.Data">
+      <Name>System.Data</Name>
+    </Reference>
+    <Reference Include="System.Xml">
+      <Name>System.XML</Name>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CryptoTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Content Include="App.ico" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent />
+    <PostBuildEvent />
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index 442fda26d..a54c454ce 100644
--- a/crypto/crypto.csproj
+++ b/crypto/crypto.csproj
@@ -1,4 +1,4 @@
-<VisualStudioProject>
+<VisualStudioProject>
     <CSHARP
         ProjectType = "Local"
         ProductVersion = "7.10.3077"
diff --git a/crypto/src/asn1/x509/X509ExtensionsGenerator.cs b/crypto/src/asn1/x509/X509ExtensionsGenerator.cs
index 58620ea5e..3b952fffa 100644
--- a/crypto/src/asn1/x509/X509ExtensionsGenerator.cs
+++ b/crypto/src/asn1/x509/X509ExtensionsGenerator.cs
@@ -5,88 +5,133 @@ using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.X509
 {
-	/// <remarks>Generator for X.509 extensions</remarks>
-	public class X509ExtensionsGenerator
-	{
-		private IDictionary extensions = Platform.CreateHashtable();
+    /// <remarks>Generator for X.509 extensions</remarks>
+    public class X509ExtensionsGenerator
+    {
+        private IDictionary extensions = Platform.CreateHashtable();
         private IList extOrdering = Platform.CreateArrayList();
 
-		/// <summary>Reset the generator</summary>
-		public void Reset()
-		{
+        private static readonly IDictionary dupsAllowed = Platform.CreateHashtable();
+
+        static X509ExtensionsGenerator()
+        {
+            dupsAllowed.Add(X509Extensions.SubjectAlternativeName, true);
+            dupsAllowed.Add(X509Extensions.IssuerAlternativeName, true);
+            dupsAllowed.Add(X509Extensions.SubjectDirectoryAttributes, true);
+            dupsAllowed.Add(X509Extensions.CertificateIssuer, true);
+
+        }
+
+
+
+        /// <summary>Reset the generator</summary>
+        public void Reset()
+        {
             extensions = Platform.CreateHashtable();
             extOrdering = Platform.CreateArrayList();
-		}
-
-		/// <summary>
-		/// Add an extension with the given oid and the passed in value to be included
-		/// in the OCTET STRING associated with the extension.
-		/// </summary>
-		/// <param name="oid">OID for the extension.</param>
-		/// <param name="critical">True if critical, false otherwise.</param>
-		/// <param name="extValue">The ASN.1 object to be included in the extension.</param>
-		public void AddExtension(
-			DerObjectIdentifier	oid,
-			bool				critical,
-			Asn1Encodable		extValue)
-		{
-			byte[] encoded;
-			try
-			{
-				encoded = extValue.GetDerEncoded();
-			}
-			catch (Exception e)
-			{
-				throw new ArgumentException("error encoding value: " + e);
-			}
-
-			this.AddExtension(oid, critical, encoded);
-		}
-
-		/// <summary>
-		/// Add an extension with the given oid and the passed in byte array to be wrapped
-		/// in the OCTET STRING associated with the extension.
-		/// </summary>
-		/// <param name="oid">OID for the extension.</param>
-		/// <param name="critical">True if critical, false otherwise.</param>
-		/// <param name="extValue">The byte array to be wrapped.</param>
-		public void AddExtension(
-			DerObjectIdentifier	oid,
-			bool				critical,
-			byte[]				extValue)
-		{
-			if (extensions.Contains(oid))
-			{
-				throw new ArgumentException("extension " + oid + " already added");
-			}
-
-			extOrdering.Add(oid);
-			extensions.Add(oid, new X509Extension(critical, new DerOctetString(extValue)));
-		}
-
-		/// <summary>Return true if there are no extension present in this generator.</summary>
-		/// <returns>True if empty, false otherwise</returns>
-		public bool IsEmpty
-		{
-			get { return extOrdering.Count < 1; }
-		}
-
-		/// <summary>Generate an X509Extensions object based on the current state of the generator.</summary>
-		/// <returns>An <c>X509Extensions</c> object</returns>
-		public X509Extensions Generate()
-		{
-			return new X509Extensions(extOrdering, extensions);
-		}
-
-        internal void AddExtension(DerObjectIdentifier oid,  X509Extension x509Extension)
+        }
+
+        /// <summary>
+        /// Add an extension with the given oid and the passed in value to be included
+        /// in the OCTET STRING associated with the extension.
+        /// </summary>
+        /// <param name="oid">OID for the extension.</param>
+        /// <param name="critical">True if critical, false otherwise.</param>
+        /// <param name="extValue">The ASN.1 object to be included in the extension.</param>
+        public void AddExtension(
+            DerObjectIdentifier oid,
+            bool critical,
+            Asn1Encodable extValue)
+        {
+            byte[] encoded;
+            try
+            {
+                encoded = extValue.GetDerEncoded();
+            }
+            catch (Exception e)
+            {
+                throw new ArgumentException("error encoding value: " + e);
+            }
+
+            this.AddExtension(oid, critical, encoded);
+        }
+
+        /// <summary>
+        /// Add an extension with the given oid and the passed in byte array to be wrapped
+        /// in the OCTET STRING associated with the extension.
+        /// </summary>
+        /// <param name="oid">OID for the extension.</param>
+        /// <param name="critical">True if critical, false otherwise.</param>
+        /// <param name="extValue">The byte array to be wrapped.</param>
+        public void AddExtension(
+            DerObjectIdentifier oid,
+            bool critical,
+            byte[] extValue)
+        {
+            if (extensions.Contains(oid))
+            {
+                if (dupsAllowed.Contains(oid))
+                {
+                    X509Extension existingExtension = (X509Extension)extensions[oid];
+
+                    Asn1Sequence seq1 = Asn1Sequence.GetInstance(DerOctetString.GetInstance(existingExtension.Value).GetOctets());
+                    Asn1EncodableVector items = Asn1EncodableVector.FromEnumerable(seq1);
+                    Asn1Sequence seq2 = Asn1Sequence.GetInstance(extValue);
+
+                    foreach (Asn1Encodable enc in seq2)
+                    {
+                        items.Add(enc);
+                    }
+
+                    extensions[oid] = new X509Extension(existingExtension.IsCritical, new DerOctetString(new DerSequence(items).GetEncoded()));
+
+                }
+                else
+                {
+                    throw new ArgumentException("extension " + oid + " already added");
+                }
+            }
+            else
+            {
+                extOrdering.Add(oid);
+                extensions.Add(oid, new X509Extension(critical, new DerOctetString(extValue)));
+            }
+        }
+
+        public void AddExtensions(X509Extensions extensions)
+        {
+            foreach (DerObjectIdentifier ident in extensions.ExtensionOids)
+            {
+                X509Extension ext = extensions.GetExtension(ident);
+                AddExtension(ident, ext.critical, ext.Value.GetOctets());
+            }
+        }
+
+
+
+        /// <summary>Return true if there are no extension present in this generator.</summary>
+        /// <returns>True if empty, false otherwise</returns>
+        public bool IsEmpty
+        {
+            get { return extOrdering.Count < 1; }
+        }
+
+        /// <summary>Generate an X509Extensions object based on the current state of the generator.</summary>
+        /// <returns>An <c>X509Extensions</c> object</returns>
+        public X509Extensions Generate()
+        {
+            return new X509Extensions(extOrdering, extensions);
+        }
+
+        internal void AddExtension(DerObjectIdentifier oid, X509Extension x509Extension)
         {
             if (extensions.Contains(oid))
-            {				
-				throw new ArgumentException  ("extension " + oid + " already added");
-			}
+            {
+                throw new ArgumentException("extension " + oid + " already added");
+            }
 
-			extOrdering.Add(oid);
-			extensions.Add(oid, x509Extension);
+            extOrdering.Add(oid);
+            extensions.Add(oid, x509Extension);
         }
     }
 }
diff --git a/crypto/src/pkcs/Pkcs10CertificationRequest.cs b/crypto/src/pkcs/Pkcs10CertificationRequest.cs
index f422e0332..28b6ddb5b 100644
--- a/crypto/src/pkcs/Pkcs10CertificationRequest.cs
+++ b/crypto/src/pkcs/Pkcs10CertificationRequest.cs
@@ -16,50 +16,51 @@ using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.X509;
 using Org.BouncyCastle.Crypto.Operators;
+using Org.BouncyCastle.Asn1.Utilities;
 
 namespace Org.BouncyCastle.Pkcs
 {
-	/// <remarks>
-	/// A class for verifying and creating Pkcs10 Certification requests.
-	/// </remarks>
-	/// <code>
-	/// CertificationRequest ::= Sequence {
-	///   certificationRequestInfo  CertificationRequestInfo,
-	///   signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
-	///   signature                 BIT STRING
-	/// }
-	///
-	/// CertificationRequestInfo ::= Sequence {
-	///   version             Integer { v1(0) } (v1,...),
-	///   subject             Name,
-	///   subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
-	///   attributes          [0] Attributes{{ CRIAttributes }}
-	///  }
-	///
-	///  Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }}
-	///
-	///  Attr { ATTRIBUTE:IOSet } ::= Sequence {
-	///    type    ATTRIBUTE.&amp;id({IOSet}),
-	///    values  Set SIZE(1..MAX) OF ATTRIBUTE.&amp;Type({IOSet}{\@type})
-	///  }
-	/// </code>
-	/// see <a href="http://www.rsasecurity.com/rsalabs/node.asp?id=2132"/>
-	public class Pkcs10CertificationRequest
-		: CertificationRequest
-	{
-		protected static readonly IDictionary algorithms = Platform.CreateHashtable();
+    /// <remarks>
+    /// A class for verifying and creating Pkcs10 Certification requests.
+    /// </remarks>
+    /// <code>
+    /// CertificationRequest ::= Sequence {
+    ///   certificationRequestInfo  CertificationRequestInfo,
+    ///   signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
+    ///   signature                 BIT STRING
+    /// }
+    ///
+    /// CertificationRequestInfo ::= Sequence {
+    ///   version             Integer { v1(0) } (v1,...),
+    ///   subject             Name,
+    ///   subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
+    ///   attributes          [0] Attributes{{ CRIAttributes }}
+    ///  }
+    ///
+    ///  Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }}
+    ///
+    ///  Attr { ATTRIBUTE:IOSet } ::= Sequence {
+    ///    type    ATTRIBUTE.&amp;id({IOSet}),
+    ///    values  Set SIZE(1..MAX) OF ATTRIBUTE.&amp;Type({IOSet}{\@type})
+    ///  }
+    /// </code>
+    /// see <a href="http://www.rsasecurity.com/rsalabs/node.asp?id=2132"/>
+    public class Pkcs10CertificationRequest
+        : CertificationRequest
+    {
+        protected static readonly IDictionary algorithms = Platform.CreateHashtable();
         protected static readonly IDictionary exParams = Platform.CreateHashtable();
         protected static readonly IDictionary keyAlgorithms = Platform.CreateHashtable();
         protected static readonly IDictionary oids = Platform.CreateHashtable();
-		protected static readonly ISet noParams = new HashSet();
-
-		static Pkcs10CertificationRequest()
-		{
-			algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption);
-			algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption);
-			algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption);
-			algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption);
-			algorithms.Add("RSAWITHMD5", PkcsObjectIdentifiers.MD5WithRsaEncryption);
+        protected static readonly ISet noParams = new HashSet();
+
+        static Pkcs10CertificationRequest()
+        {
+            algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption);
+            algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption);
+            algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption);
+            algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption);
+            algorithms.Add("RSAWITHMD5", PkcsObjectIdentifiers.MD5WithRsaEncryption);
             algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
             algorithms.Add("SHA-1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
             algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
@@ -89,38 +90,38 @@ namespace Org.BouncyCastle.Pkcs
             algorithms.Add("SHA512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
             algorithms.Add("SHA-512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption);
             algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
-			algorithms.Add("RSAWITHSHA1", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
-			algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
-			algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
-			algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
-			algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
-			algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
-			algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
-			algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1);
-			algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1);
-			algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224);
-			algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256);
-			algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384);
-			algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512);
-			algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1);
-			algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224);
-			algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256);
-			algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384);
-			algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512);
-			algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1);
-			algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
-			algorithms.Add("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
-			algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
-			algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
-			algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
-
-			//
-			// reverse mappings
-			//
+            algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+            algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+            algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+            algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
+            algorithms.Add("RSAWITHSHA1", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
+            algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
+            algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
+            algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
+            algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
+            algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
+            algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
+            algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1);
+            algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1);
+            algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224);
+            algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256);
+            algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384);
+            algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512);
+            algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1);
+            algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224);
+            algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256);
+            algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384);
+            algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512);
+            algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1);
+            algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+            algorithms.Add("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+            algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+            algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+            algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+
+            //
+            // reverse mappings
+            //
             oids.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption, "SHA1WITHRSA");
             oids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224WITHRSA");
             oids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256WITHRSA");
@@ -145,82 +146,82 @@ namespace Org.BouncyCastle.Pkcs
             oids.Add(NistObjectIdentifiers.DsaWithSha224, "SHA224WITHDSA");
             oids.Add(NistObjectIdentifiers.DsaWithSha256, "SHA256WITHDSA");
 
-			//
-			// key types
-			//
-			keyAlgorithms.Add(PkcsObjectIdentifiers.RsaEncryption, "RSA");
-			keyAlgorithms.Add(X9ObjectIdentifiers.IdDsa, "DSA");
-
-			//
-			// According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
-			// The parameters field SHALL be NULL for RSA based signature algorithms.
-			//
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1);
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224);
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256);
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384);
-			noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512);
-			noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1);
+            //
+            // key types
+            //
+            keyAlgorithms.Add(PkcsObjectIdentifiers.RsaEncryption, "RSA");
+            keyAlgorithms.Add(X9ObjectIdentifiers.IdDsa, "DSA");
+
+            //
+            // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
+            // The parameters field SHALL be NULL for RSA based signature algorithms.
+            //
+            noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1);
+            noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224);
+            noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256);
+            noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384);
+            noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512);
+            noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1);
             noParams.Add(OiwObjectIdentifiers.DsaWithSha1);
             noParams.Add(NistObjectIdentifiers.DsaWithSha224);
-			noParams.Add(NistObjectIdentifiers.DsaWithSha256);
-
-			//
-			// RFC 4491
-			//
-			noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
-			noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
-
-			//
-			// explicit params
-			//
-			AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
-			exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20));
-
-			AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance);
-			exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28));
-
-			AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
-			exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32));
-
-			AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
-			exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48));
-
-			AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
-			exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64));
-		}
-
-		private static RsassaPssParameters CreatePssParams(
-			AlgorithmIdentifier	hashAlgId,
-			int					saltSize)
-		{
-			return new RsassaPssParameters(
-				hashAlgId,
-				new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId),
-				new DerInteger(saltSize),
-				new DerInteger(1));
-		}
-
-		protected Pkcs10CertificationRequest()
-		{
-		}
-
-		public Pkcs10CertificationRequest(
-			byte[] encoded)
-			: base((Asn1Sequence) Asn1Object.FromByteArray(encoded))
-		{
-		}
-
-		public Pkcs10CertificationRequest(
-			Asn1Sequence seq)
-			: base(seq)
-		{
-		}
-
-		public Pkcs10CertificationRequest(
-			Stream input)
-			: base((Asn1Sequence) Asn1Object.FromStream(input))
-		{
+            noParams.Add(NistObjectIdentifiers.DsaWithSha256);
+
+            //
+            // RFC 4491
+            //
+            noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+            noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+
+            //
+            // explicit params
+            //
+            AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+            exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20));
+
+            AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance);
+            exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28));
+
+            AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
+            exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32));
+
+            AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
+            exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48));
+
+            AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
+            exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64));
+        }
+
+        private static RsassaPssParameters CreatePssParams(
+            AlgorithmIdentifier hashAlgId,
+            int saltSize)
+        {
+            return new RsassaPssParameters(
+                hashAlgId,
+                new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId),
+                new DerInteger(saltSize),
+                new DerInteger(1));
+        }
+
+        protected Pkcs10CertificationRequest()
+        {
+        }
+
+        public Pkcs10CertificationRequest(
+            byte[] encoded)
+            : base((Asn1Sequence)Asn1Object.FromByteArray(encoded))
+        {
+        }
+
+        public Pkcs10CertificationRequest(
+            Asn1Sequence seq)
+            : base(seq)
+        {
+        }
+
+        public Pkcs10CertificationRequest(
+            Stream input)
+            : base((Asn1Sequence)Asn1Object.FromStream(input))
+        {
         }
 
         /// <summary>
@@ -232,14 +233,14 @@ namespace Org.BouncyCastle.Pkcs
         /// <param name="attributes">ASN1Set of Attributes.</param>
         /// <param name="signingKey">Matching Private key for nominated (above) public key to be used to sign the request.</param>
         public Pkcs10CertificationRequest(
-			string					signatureAlgorithm,
-			X509Name				subject,
-			AsymmetricKeyParameter	publicKey,
-			Asn1Set					attributes,
-			AsymmetricKeyParameter	signingKey)
+            string signatureAlgorithm,
+            X509Name subject,
+            AsymmetricKeyParameter publicKey,
+            Asn1Set attributes,
+            AsymmetricKeyParameter signingKey)
             : this(new Asn1SignatureFactory(signatureAlgorithm, signingKey), subject, publicKey, attributes)
-		{
-		}
+        {
+        }
 
         /// <summary>
         /// Instantiate a Pkcs10CertificationRequest object with the necessary credentials.
@@ -286,7 +287,7 @@ namespace Org.BouncyCastle.Pkcs
         }
 
         private void Init(
-            ISignatureFactory signatureFactory, 
+            ISignatureFactory signatureFactory,
             X509Name subject,
             AsymmetricKeyParameter publicKey,
             Asn1Set attributes)
@@ -330,24 +331,24 @@ namespace Org.BouncyCastle.Pkcs
         /// </summary>
         /// <returns>The public key.</returns>
         public AsymmetricKeyParameter GetPublicKey()
-		{
-			return PublicKeyFactory.CreateKey(reqInfo.SubjectPublicKeyInfo);
-		}
-
-		/// <summary>
-		/// Verify Pkcs10 Cert Request is valid.
-		/// </summary>
-		/// <returns>true = valid.</returns>
-		public bool Verify()
-		{
-			return Verify(this.GetPublicKey());
-		}
-
-		public bool Verify(
-			AsymmetricKeyParameter publicKey)
-		{
+        {
+            return PublicKeyFactory.CreateKey(reqInfo.SubjectPublicKeyInfo);
+        }
+
+        /// <summary>
+        /// Verify Pkcs10 Cert Request is valid.
+        /// </summary>
+        /// <returns>true = valid.</returns>
+        public bool Verify()
+        {
+            return Verify(this.GetPublicKey());
+        }
+
+        public bool Verify(
+            AsymmetricKeyParameter publicKey)
+        {
             return Verify(new Asn1VerifierFactoryProvider(publicKey));
-		}
+        }
 
         public bool Verify(
             IVerifierFactoryProvider verifierProvider)
@@ -387,82 +388,82 @@ namespace Org.BouncyCastle.Pkcs
 
         // TODO Figure out how to set parameters on an ISigner
         private void SetSignatureParameters(
-			ISigner			signature,
-			Asn1Encodable	asn1Params)
-		{
-			if (asn1Params != null && !(asn1Params is Asn1Null))
-			{
-//				AlgorithmParameters sigParams = AlgorithmParameters.GetInstance(signature.getAlgorithm());
-//
-//				try
-//				{
-//					sigParams.init(asn1Params.ToAsn1Object().GetDerEncoded());
-//				}
-//				catch (IOException e)
-//				{
-//					throw new SignatureException("IOException decoding parameters: " + e.Message);
-//				}
-
-				if (Platform.EndsWith(signature.AlgorithmName, "MGF1"))
-				{
-					throw Platform.CreateNotImplementedException("signature algorithm with MGF1");
-
-//					try
-//					{
-//						signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class));
-//					}
-//					catch (GeneralSecurityException e)
-//					{
-//						throw new SignatureException("Exception extracting parameters: " + e.getMessage());
-//					}
-				}
-			}
-		}
-
-		internal static string GetSignatureName(
-			AlgorithmIdentifier sigAlgId)
-		{
-			Asn1Encodable asn1Params = sigAlgId.Parameters;
-
-			if (asn1Params != null && !(asn1Params is Asn1Null))
-			{
+            ISigner signature,
+            Asn1Encodable asn1Params)
+        {
+            if (asn1Params != null && !(asn1Params is Asn1Null))
+            {
+                //				AlgorithmParameters sigParams = AlgorithmParameters.GetInstance(signature.getAlgorithm());
+                //
+                //				try
+                //				{
+                //					sigParams.init(asn1Params.ToAsn1Object().GetDerEncoded());
+                //				}
+                //				catch (IOException e)
+                //				{
+                //					throw new SignatureException("IOException decoding parameters: " + e.Message);
+                //				}
+
+                if (Platform.EndsWith(signature.AlgorithmName, "MGF1"))
+                {
+                    throw Platform.CreateNotImplementedException("signature algorithm with MGF1");
+
+                    //					try
+                    //					{
+                    //						signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class));
+                    //					}
+                    //					catch (GeneralSecurityException e)
+                    //					{
+                    //						throw new SignatureException("Exception extracting parameters: " + e.getMessage());
+                    //					}
+                }
+            }
+        }
+
+        internal static string GetSignatureName(
+            AlgorithmIdentifier sigAlgId)
+        {
+            Asn1Encodable asn1Params = sigAlgId.Parameters;
+
+            if (asn1Params != null && !(asn1Params is Asn1Null))
+            {
                 if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
-				{
-					RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(asn1Params);
+                {
+                    RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(asn1Params);
                     return GetDigestAlgName(rsaParams.HashAlgorithm.Algorithm) + "withRSAandMGF1";
-				}
-			}
+                }
+            }
 
             return sigAlgId.Algorithm.Id;
-		}
-
-		private static string GetDigestAlgName(
-			DerObjectIdentifier digestAlgOID)
-		{
-			if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID))
-			{
-				return "MD5";
-			}
-			else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID))
-			{
-				return "SHA1";
-			}
-			else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID))
-			{
-				return "SHA224";
-			}
-			else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID))
-			{
-				return "SHA256";
-			}
-			else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID))
-			{
-				return "SHA384";
-			}
-			else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID))
-			{
-				return "SHA512";
-			}
+        }
+
+        private static string GetDigestAlgName(
+            DerObjectIdentifier digestAlgOID)
+        {
+            if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID))
+            {
+                return "MD5";
+            }
+            else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID))
+            {
+                return "SHA1";
+            }
+            else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID))
+            {
+                return "SHA224";
+            }
+            else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID))
+            {
+                return "SHA256";
+            }
+            else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID))
+            {
+                return "SHA384";
+            }
+            else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID))
+            {
+                return "SHA512";
+            }
             else if (NistObjectIdentifiers.IdSha512_224.Equals(digestAlgOID))
             {
                 return "SHA512(224)";
@@ -472,25 +473,83 @@ namespace Org.BouncyCastle.Pkcs
                 return "SHA512(256)";
             }
             else if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID))
-			{
-				return "RIPEMD128";
-			}
-			else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID))
-			{
-				return "RIPEMD160";
-			}
-			else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID))
-			{
-				return "RIPEMD256";
-			}
-			else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID))
-			{
-				return "GOST3411";
-			}
-			else
-			{
-				return digestAlgOID.Id;
-			}
-		}
-	}
+            {
+                return "RIPEMD128";
+            }
+            else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID))
+            {
+                return "RIPEMD160";
+            }
+            else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID))
+            {
+                return "RIPEMD256";
+            }
+            else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID))
+            {
+                return "GOST3411";
+            }
+            else
+            {
+                return digestAlgOID.Id;
+            }
+        }
+
+        /// <summary>
+        /// Returns X509Extensions if the attribute can be found and returns the extensions block.
+        /// </summary>
+        /// <returns>X509Extensions block or null if one cannot be found.</returns>
+        public X509Extensions GetX509Extensions()
+        {
+            if (reqInfo.Attributes != null)
+            {
+                foreach (Asn1Encodable item in reqInfo.Attributes)
+                {
+                    AttributePkcs attributePkcs;
+                    try
+                    {
+                        attributePkcs = AttributePkcs.GetInstance(item);
+
+                    }
+                    catch (ArgumentException ex)
+                    {
+                        throw new ArgumentException("encountered non PKCS attribute in extensions block", ex);
+                    }
+
+                    if (attributePkcs.AttrType.Equals(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest))
+                    {
+                        X509ExtensionsGenerator generator = new X509ExtensionsGenerator();
+
+                        Asn1Sequence extensionSequence = Asn1Sequence.GetInstance(attributePkcs.AttrValues[0]);
+
+
+                        foreach (Asn1Encodable seqItem in extensionSequence)
+                        {
+
+                            Asn1Sequence itemSeq = Asn1Sequence.GetInstance(seqItem);
+                            bool critical = itemSeq.Count == 3 && DerBoolean.GetInstance(itemSeq[1]).IsTrue;
+
+                            if (itemSeq.Count == 2)
+                            {
+                                generator.AddExtension(DerObjectIdentifier.GetInstance(itemSeq[0]), false, Asn1OctetString.GetInstance(itemSeq[1]).GetOctets());
+                            }
+                            else if (itemSeq.Count == 3)
+                            {
+                                generator.AddExtension(DerObjectIdentifier.GetInstance(itemSeq[0]), DerBoolean.GetInstance(itemSeq[1]).IsTrue, Asn1OctetString.GetInstance(itemSeq[2]).GetOctets());
+                            }
+                            else
+                            {
+                                throw new ArgumentException("incorrect sequence size of X509Extension got " + itemSeq.Count + " expected 2 or 3");
+                            }
+                        }
+
+                        return generator.Generate();
+                    }
+
+                }
+            }
+
+            return null;
+        }
+
+    }
 }
diff --git a/crypto/test/src/asn1/test/X509ExtensionsTest.cs b/crypto/test/src/asn1/test/X509ExtensionsTest.cs
index f1efd3a9b..71bb5ef67 100644
--- a/crypto/test/src/asn1/test/X509ExtensionsTest.cs
+++ b/crypto/test/src/asn1/test/X509ExtensionsTest.cs
@@ -7,111 +7,219 @@ using Org.BouncyCastle.Utilities.Test;
 
 namespace Org.BouncyCastle.Asn1.Tests
 {
-	[TestFixture]
-	public class X509ExtensionsTest
-		: SimpleTest
-	{
-		private static readonly DerObjectIdentifier Oid1 = new DerObjectIdentifier("1.2.1");
-		private static readonly DerObjectIdentifier Oid2 = new DerObjectIdentifier("1.2.2");
-		private static readonly DerObjectIdentifier Oid3 = new DerObjectIdentifier("1.2.3");
-
-		public override string Name
-		{
-			get { return "X509Extensions"; }
-		}
-
-		public override void PerformTest()
-		{
-			X509ExtensionsGenerator gen = new X509ExtensionsGenerator();
-
-			gen.AddExtension(Oid1, true, new byte[20]);
-			gen.AddExtension(Oid2, true, new byte[20]);
-
-			X509Extensions ext1 = gen.Generate();
-			X509Extensions ext2 = gen.Generate();
-
-			if (!ext1.Equals(ext2))
-			{
-				Fail("Equals test failed");
-			}
-
-			gen.Reset();
-
-			gen.AddExtension(Oid2, true, new byte[20]);
-			gen.AddExtension(Oid1, true, new byte[20]);
-
-			ext2 = gen.Generate();
-
-			if (ext1.Equals(ext2))
-			{
-				Fail("inequality test failed");
-			}
-
-			if (!ext1.Equivalent(ext2))
-			{
-				Fail("equivalence true failed");
-			}
-
-			gen.Reset();
-
-			gen.AddExtension(Oid1, true, new byte[22]);
-			gen.AddExtension(Oid2, true, new byte[20]);
-
-			ext2 = gen.Generate();
-
-			if (ext1.Equals(ext2))
-			{
-				Fail("inequality 1 failed");
-			}
-
-			if (ext1.Equivalent(ext2))
-			{
-				Fail("non-equivalence 1 failed");
-			}
-
-			gen.Reset();
-
-			gen.AddExtension(Oid3, true, new byte[20]);
-			gen.AddExtension(Oid2, true, new byte[20]);
-
-			ext2 = gen.Generate();
-
-			if (ext1.Equals(ext2))
-			{
-				Fail("inequality 2 failed");
-			}
-
-			if (ext1.Equivalent(ext2))
-			{
-				Fail("non-equivalence 2 failed");
-			}
-
-			try
-			{
-				gen.AddExtension(Oid2, true, new byte[20]);
-				Fail("repeated oid");
-			}
-			catch (ArgumentException e)
-			{
-				if (!e.Message.Equals("extension 1.2.2 already added"))
-				{
-					Fail("wrong exception on repeated oid: " + e.Message);
-				}
-			}
-		}
-
-		public static void Main(
-			string[] args)
-		{
-			RunTest(new X509ExtensionsTest());
-		}
-
-		[Test]
-		public void TestFunction()
-		{
-			string resultText = Perform().ToString();
-
-			Assert.AreEqual(Name + ": Okay", resultText);
-		}
-	}
+    [TestFixture]
+    public class X509ExtensionsTest
+        : SimpleTest
+    {
+        private static readonly DerObjectIdentifier Oid1 = new DerObjectIdentifier("1.2.1");
+        private static readonly DerObjectIdentifier Oid2 = new DerObjectIdentifier("1.2.2");
+        private static readonly DerObjectIdentifier Oid3 = new DerObjectIdentifier("1.2.3");
+
+        public override string Name
+        {
+            get { return "X509Extensions"; }
+        }
+
+
+        [Test]
+        public void TestDuplicateExtensions()
+        {
+
+            // Testing for handling of duplicates
+
+            GeneralName name1 = new GeneralName(GeneralName.DnsName, "bc1.local");
+            GeneralName name2 = new GeneralName(GeneralName.DnsName, "bc2.local");
+
+
+            X509ExtensionsGenerator extensionsGenerator = new X509ExtensionsGenerator();
+            extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 })));
+            extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 })));
+
+            //
+            // Generate and deserialise.
+            //
+            X509Extensions ext = X509Extensions.GetInstance(Asn1Sequence.GetInstance(extensionsGenerator.Generate().GetEncoded()));
+            X509Extension returnedExtension = ext.GetExtension(X509Extensions.SubjectAlternativeName);
+            Asn1Sequence seq = Asn1Sequence.GetInstance(returnedExtension.GetParsedValue());
+
+
+            //
+            // Check expected order and value.
+            //
+            if (!GeneralName.GetInstance(seq[0]).Equals(name1))
+            {
+                Fail("expected name 1");
+            }
+
+            if (!GeneralName.GetInstance(seq[1]).Equals(name2))
+            {
+                Fail("expected name 2");
+            }
+
+
+            //
+            // Test we can load dup extensions into a new generator
+            //
+
+            X509ExtensionsGenerator genX = new X509ExtensionsGenerator();
+            genX.AddExtensions(ext);
+
+            ext = X509Extensions.GetInstance(Asn1Sequence.GetInstance(genX.Generate().GetEncoded()));
+            returnedExtension = ext.GetExtension(X509Extensions.SubjectAlternativeName);
+            seq = Asn1Sequence.GetInstance(returnedExtension.GetParsedValue());
+
+
+
+            //
+            // Check expected order and value.
+            //
+            if (!GeneralName.GetInstance(seq[0]).Equals(name1))
+            {
+                Fail("expected name 1");
+            }
+
+            if (!GeneralName.GetInstance(seq[1]).Equals(name2))
+            {
+                Fail("expected name 2");
+            }
+
+
+
+
+        }
+
+
+        [Test]
+        public void TestAllowedDuplicateExtensions()
+        {
+
+            // Testing for handling of duplicates
+
+            GeneralName name1 = new GeneralName(GeneralName.DnsName, "bc1.local");
+            GeneralName name2 = new GeneralName(GeneralName.DnsName, "bc2.local");
+
+
+            X509ExtensionsGenerator extensionsGenerator = new X509ExtensionsGenerator();
+            extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 })));
+            extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 })));
+
+            extensionsGenerator.AddExtension(X509Extensions.IssuerAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 })));
+            extensionsGenerator.AddExtension(X509Extensions.IssuerAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 })));
+
+
+            extensionsGenerator.AddExtension(X509Extensions.SubjectDirectoryAttributes, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 })));
+            extensionsGenerator.AddExtension(X509Extensions.SubjectDirectoryAttributes, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 })));
+
+            extensionsGenerator.AddExtension(X509Extensions.CertificateIssuer, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 })));
+            extensionsGenerator.AddExtension(X509Extensions.CertificateIssuer, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 })));
+
+
+            extensionsGenerator.AddExtension(X509Extensions.AuditIdentity, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 })));
+            try
+            {
+                extensionsGenerator.AddExtension(X509Extensions.AuditIdentity, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 })));
+                Fail("Expected exception, not a white listed duplicate.");
+            }
+            catch (Exception ex)
+            {
+                // ok
+            }
+
+        }
+
+
+        public override void PerformTest()
+        {
+            X509ExtensionsGenerator gen = new X509ExtensionsGenerator();
+
+            gen.AddExtension(Oid1, true, new byte[20]);
+            gen.AddExtension(Oid2, true, new byte[20]);
+
+            X509Extensions ext1 = gen.Generate();
+            X509Extensions ext2 = gen.Generate();
+
+            if (!ext1.Equals(ext2))
+            {
+                Fail("Equals test failed");
+            }
+
+            gen.Reset();
+
+            gen.AddExtension(Oid2, true, new byte[20]);
+            gen.AddExtension(Oid1, true, new byte[20]);
+
+            ext2 = gen.Generate();
+
+            if (ext1.Equals(ext2))
+            {
+                Fail("inequality test failed");
+            }
+
+            if (!ext1.Equivalent(ext2))
+            {
+                Fail("equivalence true failed");
+            }
+
+            gen.Reset();
+
+            gen.AddExtension(Oid1, true, new byte[22]);
+            gen.AddExtension(Oid2, true, new byte[20]);
+
+            ext2 = gen.Generate();
+
+            if (ext1.Equals(ext2))
+            {
+                Fail("inequality 1 failed");
+            }
+
+            if (ext1.Equivalent(ext2))
+            {
+                Fail("non-equivalence 1 failed");
+            }
+
+            gen.Reset();
+
+            gen.AddExtension(Oid3, true, new byte[20]);
+            gen.AddExtension(Oid2, true, new byte[20]);
+
+            ext2 = gen.Generate();
+
+            if (ext1.Equals(ext2))
+            {
+                Fail("inequality 2 failed");
+            }
+
+            if (ext1.Equivalent(ext2))
+            {
+                Fail("non-equivalence 2 failed");
+            }
+
+            try
+            {
+                gen.AddExtension(Oid2, true, new byte[20]);
+                Fail("repeated oid");
+            }
+            catch (ArgumentException e)
+            {
+                if (!e.Message.Equals("extension 1.2.2 already added"))
+                {
+                    Fail("wrong exception on repeated oid: " + e.Message);
+                }
+            }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            RunTest(new X509ExtensionsTest());
+        }
+
+        [Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
 }
diff --git a/crypto/test/src/test/PKCS10CertRequestTest.cs b/crypto/test/src/test/PKCS10CertRequestTest.cs
index ea27d5111..26a8ab20c 100644
--- a/crypto/test/src/test/PKCS10CertRequestTest.cs
+++ b/crypto/test/src/test/PKCS10CertRequestTest.cs
@@ -1,11 +1,12 @@
 using System;
 using System.Collections;
-
+using System.IO;
 using NUnit.Framework;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.CryptoPro;
 using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.Utilities;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto;
@@ -15,7 +16,9 @@ using Org.BouncyCastle.Math.EC;
 using Org.BouncyCastle.Pkcs;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO.Pem;
 using Org.BouncyCastle.Utilities.Test;
+using Org.BouncyCastle.X509;
 using Org.BouncyCastle.X509.Extension;
 
 namespace Org.BouncyCastle.Tests
@@ -26,27 +29,27 @@ namespace Org.BouncyCastle.Tests
     {
         private static readonly byte[] gost3410EC_A = Base64.Decode(
               "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV"
-            +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ"
-            +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B"
-            +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ"
-            +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl"
-            +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA==");
+            + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ"
+            + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B"
+            + "A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ"
+            + "GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl"
+            + "JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA==");
 
         private static readonly byte[] gost3410EC_B = Base64.Decode(
               "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG"
-            +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1"
-            +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC"
-            +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7"
-            +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy"
-            +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq");
+            + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1"
+            + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC"
+            + "HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7"
+            + "7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy"
+            + "wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq");
 
         private static readonly byte[] gost3410EC_C = Base64.Decode(
               "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM"
-            +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD"
-            +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD"
-            +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa"
-            +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8"
-            +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ==");
+            + "dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD"
+            + "VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD"
+            + "BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa"
+            + "UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8"
+            + "Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ==");
 
         private static readonly byte[] gost3410EC_ExA = Base64.Decode(
               "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV"
@@ -70,13 +73,13 @@ namespace Org.BouncyCastle.Tests
         }
 
         private void generationTest(
-            int		keySize,
-            string	keyName,
-            string	sigName)
+            int keySize,
+            string keyName,
+            string sigName)
         {
             IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator(keyName);
 
-//			kpg.initialize(keySize);
+            //			kpg.initialize(keySize);
             kpg.Init(new KeyGenerationParameters(new SecureRandom(), keySize));
 
             AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();
@@ -123,8 +126,8 @@ namespace Org.BouncyCastle.Tests
          * we generate a self signed certificate for the sake of testing - SHA224withECDSA
          */
         private void createECRequest(
-            string				algorithm,
-            DerObjectIdentifier	algOid)
+            string algorithm,
+            DerObjectIdentifier algOid)
         {
             X9ECParameters x9 = ECNamedCurveTable.GetByName("secp521r1");
             ECCurve curve = x9.Curve;
@@ -135,20 +138,20 @@ namespace Org.BouncyCastle.Tests
                 spec);
 
             ECPublicKeyParameters pubKey = new ECPublicKeyParameters(
-//				curve.DecodePoint(Hex.Decode("026BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q
+                //				curve.DecodePoint(Hex.Decode("026BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q
                 curve.DecodePoint(Hex.Decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q
                 spec);
 
-//			//
-//			// set up the keys
-//			//
-//			AsymmetricKeyParameter privKey;
-//			AsymmetricKeyParameter pubKey;
-//
-//			KeyFactory fact = KeyFactory.getInstance("ECDSA");
-//
-//			privKey = fact.generatePrivate(privKeySpec);
-//			pubKey = fact.generatePublic(pubKeySpec);
+            //			//
+            //			// set up the keys
+            //			//
+            //			AsymmetricKeyParameter privKey;
+            //			AsymmetricKeyParameter pubKey;
+            //
+            //			KeyFactory fact = KeyFactory.getInstance("ECDSA");
+            //
+            //			privKey = fact.generatePrivate(privKeySpec);
+            //			pubKey = fact.generatePublic(pubKeySpec);
 
             Pkcs10CertificationRequest req = new Pkcs10CertificationRequest(
                 algorithm, new X509Name("CN=XXX"), pubKey, null, privKey);
@@ -166,7 +169,7 @@ namespace Org.BouncyCastle.Tests
             //
             // try with point compression turned off
             //
-//			((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED");
+            //			((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED");
             ECPoint q = pubKey.Q.Normalize();
             pubKey = new ECPublicKeyParameters(
                 pubKey.AlgorithmName,
@@ -266,26 +269,26 @@ namespace Org.BouncyCastle.Tests
         private void createPssTest(
             string algorithm)
         {
-//			RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+            //			RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
             RsaKeyParameters pubKey = new RsaKeyParameters(false,
-                new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
-                new BigInteger("010001",16));
+                new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137", 16),
+                new BigInteger("010001", 16));
 
-//			RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec(
+            //			RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec(
             RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
-                new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
-                new BigInteger("010001",16),
-                new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16),
-                new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16),
-                new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16),
-                new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16),
-                new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16),
-                new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16));
-
-//			KeyFactory  fact = KeyFactory.getInstance("RSA", "BC");
-//
-//			PrivateKey privKey = fact.generatePrivate(privKeySpec);
-//			PublicKey pubKey = fact.generatePublic(pubKeySpec);
+                new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137", 16),
+                new BigInteger("010001", 16),
+                new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325", 16),
+                new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443", 16),
+                new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd", 16),
+                new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979", 16),
+                new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729", 16),
+                new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d", 16));
+
+            //			KeyFactory  fact = KeyFactory.getInstance("RSA", "BC");
+            //
+            //			PrivateKey privKey = fact.generatePrivate(privKeySpec);
+            //			PublicKey pubKey = fact.generatePublic(pubKeySpec);
 
             Pkcs10CertificationRequest req = new Pkcs10CertificationRequest(
                 algorithm, new X509Name("CN=XXX"), pubKey, null, privKey);
@@ -360,6 +363,8 @@ namespace Org.BouncyCastle.Tests
 
         public override void PerformTest()
         {
+
+
             generationTest(512, "RSA", "SHA1withRSA");
             generationTest(512, "GOST3410", "GOST3411withGOST3410");
 
@@ -410,7 +415,7 @@ namespace Org.BouncyCastle.Tests
             ECCurve curve = x9.Curve;
             ECDomainParameters ecSpec = new ECDomainParameters(curve, x9.G, x9.N, x9.H);
 
-//			g.initialize(ecSpec, new SecureRandom());
+            //			g.initialize(ecSpec, new SecureRandom());
             g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom()));
 
             AsymmetricCipherKeyPair kp = g.GenerateKeyPair();
@@ -432,14 +437,119 @@ namespace Org.BouncyCastle.Tests
             createECGostRequest();
 
             // TODO The setting of parameters for MGF algorithms is not implemented
-//			createPssTest("SHA1withRSAandMGF1");
-//			createPssTest("SHA224withRSAandMGF1");
-//			createPssTest("SHA256withRSAandMGF1");
-//			createPssTest("SHA384withRSAandMGF1");
+            //			createPssTest("SHA1withRSAandMGF1");
+            //			createPssTest("SHA224withRSAandMGF1");
+            //			createPssTest("SHA256withRSAandMGF1");
+            //			createPssTest("SHA384withRSAandMGF1");
 
             nullPointerTest();
         }
 
+
+
+        [Test]
+        public void BrokenRequestWithDuplicateExtension()
+        {
+
+            String keyName = "RSA";
+            int keySize = 2048;
+
+            String sigName = "SHA256withRSA";
+
+            IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator(keyName);
+
+            //			kpg.initialize(keySize);
+            kpg.Init(new KeyGenerationParameters(new SecureRandom(), keySize));
+
+            AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();
+
+            IDictionary attrs = new Hashtable();
+            attrs.Add(X509Name.C, "AU");
+            attrs.Add(X509Name.O, "The Legion of the Bouncy Castle");
+            attrs.Add(X509Name.L, "Melbourne");
+            attrs.Add(X509Name.ST, "Victoria");
+            attrs.Add(X509Name.EmailAddress, "feedback-crypto@bouncycastle.org");
+
+            IList order = new ArrayList();
+            order.Add(X509Name.C);
+            order.Add(X509Name.O);
+            order.Add(X509Name.L);
+            order.Add(X509Name.ST);
+            order.Add(X509Name.EmailAddress);
+
+            X509Name subject = new X509Name(order, attrs);
+
+            //
+            // This is simulate the creation of a certification request with duplicate extensions.
+            //
+
+            GeneralName name1 = new GeneralName(GeneralName.DnsName, "bc1.local");
+            GeneralName name2 = new GeneralName(GeneralName.DnsName, "bc2.local");
+
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            Asn1EncodableVector e1 = new Asn1EncodableVector();
+            e1.Add(X509Extensions.SubjectAlternativeName);
+            e1.Add(new DerOctetString(new GeneralNames(name1).GetEncoded()));
+
+            Asn1EncodableVector e2 = new Asn1EncodableVector();
+            e2.Add(X509Extensions.SubjectAlternativeName);
+            e2.Add(new DerOctetString(new GeneralNames(name2).GetEncoded()));
+
+            v.Add(new DerSequence(e1));
+            v.Add(new DerSequence(e2));
+
+            AttributePkcs attribute = new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(new DerSequence(v)));
+
+            Pkcs10CertificationRequest req1 = new Pkcs10CertificationRequest(
+                sigName,
+                subject,
+                kp.Public,
+                new DerSet(attribute),
+                kp.Private);
+
+
+            // Round trip serialisation
+            byte[] bytes = req1.GetEncoded();
+            Pkcs10CertificationRequest req2 = new Pkcs10CertificationRequest(bytes);
+
+
+            //
+            // Check verification after round tripping serialisation.
+            //
+
+            if (!req2.Verify())
+            {
+                Fail(sigName + ": Failed Verify check.");
+            }
+
+            if (!req2.GetPublicKey().Equals(req1.GetPublicKey()))
+            {
+                Fail(keyName + ": Failed public key check.");
+            }
+
+            //
+            // Disassemble the attributes with the duplicate extensions.
+            //
+
+            var extensions = req2.GetX509Extensions();
+
+            X509Extension returnedExtension = extensions.GetExtension(X509Extensions.SubjectAlternativeName);
+            Asn1Sequence seq = Asn1Sequence.GetInstance(returnedExtension.GetParsedValue());
+
+            //
+            // Check expected order and value.
+            //
+            if (!GeneralName.GetInstance(seq[0]).Equals(name1))
+            {
+                Fail("expected name 1");
+            }
+
+            if (!GeneralName.GetInstance(seq[1]).Equals(name2))
+            {
+                Fail("expected name 2");
+            }
+        }
+
         public static void Main(
             string[] args)
         {
diff --git a/csharp.sln b/csharp.sln
index ce64a084a..3b0413e9e 100644
--- a/csharp.sln
+++ b/csharp.sln
@@ -1,29 +1,30 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31624.102
+MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "crypto", "crypto\crypto.csproj", "{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "crypto-test", "crypto-test\crypto-test.csproj", "{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
 EndProject
 Global
-	GlobalSection(SolutionConfiguration) = preSolution
-		Debug = Debug
-		Release = Release
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
 	EndGlobalSection
-	GlobalSection(ProjectConfiguration) = postSolution
-		{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Debug.ActiveCfg = Debug|.NET
-		{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Debug.Build.0 = Debug|.NET
-		{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Release.ActiveCfg = Release|.NET
-		{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Release.Build.0 = Release|.NET
-		{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Debug.ActiveCfg = Debug|.NET
-		{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Debug.Build.0 = Debug|.NET
-		{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Release.ActiveCfg = Release|.NET
-		{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Release.Build.0 = Release|.NET
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
 	EndGlobalSection
-	GlobalSection(ExtensibilityAddIns) = postSolution
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {93DA6E72-9E82-46AE-A4EC-24E6B9389191}
 	EndGlobalSection
 EndGlobal