summary refs log tree commit diff
path: root/crypto/src/asn1
diff options
context:
space:
mode:
authormw <megan@cryptoworkshop.com>2021-09-01 16:00:23 +1000
committermw <megan@cryptoworkshop.com>2021-09-01 16:00:23 +1000
commit0b0f03c598b558c7acf79a969315a8d2e0aa1f1b (patch)
treeeb8091bd81be5d8225a38ac8947594d7f694a3c6 /crypto/src/asn1
parentfixed typos (diff)
downloadBouncyCastle.NET-ed25519-0b0f03c598b558c7acf79a969315a8d2e0aa1f1b.tar.xz
Issue #1
Added logic to handle duplicate extensions.
New method on Pkcs10CertificationRequest for extracting X509Extensions
Tests
Diffstat (limited to 'crypto/src/asn1')
-rw-r--r--crypto/src/asn1/x509/X509ExtensionsGenerator.cs195
1 files changed, 120 insertions, 75 deletions
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);
         }
     }
 }