summary refs log tree commit diff
path: root/crypto/src/x509/extension
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/x509/extension')
-rw-r--r--crypto/src/x509/extension/AuthorityKeyIdentifierStructure.cs102
-rw-r--r--crypto/src/x509/extension/SubjectKeyIdentifierStructure.cs49
-rw-r--r--crypto/src/x509/extension/X509ExtensionUtil.cs89
3 files changed, 240 insertions, 0 deletions
diff --git a/crypto/src/x509/extension/AuthorityKeyIdentifierStructure.cs b/crypto/src/x509/extension/AuthorityKeyIdentifierStructure.cs
new file mode 100644
index 000000000..006dc009b
--- /dev/null
+++ b/crypto/src/x509/extension/AuthorityKeyIdentifierStructure.cs
@@ -0,0 +1,102 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Security.Certificates;
+
+namespace Org.BouncyCastle.X509.Extension
+{
+	/// <remarks>A high level authority key identifier.</remarks>
+	public class AuthorityKeyIdentifierStructure
+		: AuthorityKeyIdentifier
+	{
+		/**
+		 * Constructor which will take the byte[] returned from getExtensionValue()
+		 *
+		 * @param encodedValue a DER octet encoded string with the extension structure in it.
+		 * @throws IOException on parsing errors.
+		 */
+		// TODO Add a functional constructor from byte[]?
+		public AuthorityKeyIdentifierStructure(
+			Asn1OctetString encodedValue)
+			: base((Asn1Sequence) X509ExtensionUtilities.FromExtensionValue(encodedValue))
+		{
+		}
+
+		private static Asn1Sequence FromCertificate(
+			X509Certificate certificate)
+		{
+			try
+			{
+				GeneralName genName = new GeneralName(
+					PrincipalUtilities.GetIssuerX509Principal(certificate));
+
+				if (certificate.Version == 3)
+				{
+					Asn1OctetString ext = certificate.GetExtensionValue(X509Extensions.SubjectKeyIdentifier);
+
+					if (ext != null)
+					{
+						Asn1OctetString str = (Asn1OctetString) X509ExtensionUtilities.FromExtensionValue(ext);
+
+						return (Asn1Sequence) new AuthorityKeyIdentifier(
+							str.GetOctets(), new GeneralNames(genName), certificate.SerialNumber).ToAsn1Object();
+					}
+				}
+
+				SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(
+					certificate.GetPublicKey());
+
+				return (Asn1Sequence) new AuthorityKeyIdentifier(
+					info, new GeneralNames(genName), certificate.SerialNumber).ToAsn1Object();
+			}
+			catch (Exception e)
+			{
+				throw new CertificateParsingException("Exception extracting certificate details", e);
+			}
+		}
+
+		private static Asn1Sequence FromKey(
+			AsymmetricKeyParameter pubKey)
+		{
+			try
+			{
+				SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey);
+
+				return (Asn1Sequence) new AuthorityKeyIdentifier(info).ToAsn1Object();
+			}
+			catch (Exception e)
+			{
+				throw new InvalidKeyException("can't process key: " + e);
+			}
+		}
+
+		/**
+		 * Create an AuthorityKeyIdentifier using the passed in certificate's public
+		 * key, issuer and serial number.
+		 *
+		 * @param certificate the certificate providing the information.
+		 * @throws CertificateParsingException if there is a problem processing the certificate
+		 */
+		public AuthorityKeyIdentifierStructure(
+			X509Certificate certificate)
+			: base(FromCertificate(certificate))
+		{
+		}
+
+		/**
+		 * Create an AuthorityKeyIdentifier using just the hash of the
+		 * public key.
+		 *
+		 * @param pubKey the key to generate the hash from.
+		 * @throws InvalidKeyException if there is a problem using the key.
+		 */
+		public AuthorityKeyIdentifierStructure(
+			AsymmetricKeyParameter pubKey)
+			: base(FromKey(pubKey))
+		{
+		}
+	}
+}
diff --git a/crypto/src/x509/extension/SubjectKeyIdentifierStructure.cs b/crypto/src/x509/extension/SubjectKeyIdentifierStructure.cs
new file mode 100644
index 000000000..4c7b79ab8
--- /dev/null
+++ b/crypto/src/x509/extension/SubjectKeyIdentifierStructure.cs
@@ -0,0 +1,49 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Security.Certificates;
+
+namespace Org.BouncyCastle.X509.Extension
+{
+	/**
+	 * A high level subject key identifier.
+	 */
+	public class SubjectKeyIdentifierStructure
+		: SubjectKeyIdentifier
+	{
+		/**
+		 * Constructor which will take the byte[] returned from getExtensionValue()
+		 *
+		 * @param encodedValue a DER octet encoded string with the extension structure in it.
+		 * @throws IOException on parsing errors.
+		 */
+		public SubjectKeyIdentifierStructure(
+			Asn1OctetString encodedValue)
+			: base((Asn1OctetString) X509ExtensionUtilities.FromExtensionValue(encodedValue))
+		{
+		}
+
+		private static Asn1OctetString FromPublicKey(
+			AsymmetricKeyParameter pubKey)
+		{
+			try
+			{
+				SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey);
+
+				return (Asn1OctetString) new SubjectKeyIdentifier(info).ToAsn1Object();
+			}
+			catch (Exception e)
+			{
+				throw new CertificateParsingException("Exception extracting certificate details: " + e.ToString());
+			}
+		}
+
+		public SubjectKeyIdentifierStructure(
+			AsymmetricKeyParameter pubKey)
+			: base(FromPublicKey(pubKey))
+		{
+		}
+	}
+}
diff --git a/crypto/src/x509/extension/X509ExtensionUtil.cs b/crypto/src/x509/extension/X509ExtensionUtil.cs
new file mode 100644
index 000000000..845a87bad
--- /dev/null
+++ b/crypto/src/x509/extension/X509ExtensionUtil.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Security.Certificates;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.X509.Extension
+{
+	public class X509ExtensionUtilities
+	{
+		public static Asn1Object FromExtensionValue(
+			Asn1OctetString extensionValue)
+		{
+			return Asn1Object.FromByteArray(extensionValue.GetOctets());
+		}
+
+		public static ICollection GetIssuerAlternativeNames(
+			X509Certificate cert)
+		{
+			Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.IssuerAlternativeName);
+
+			return GetAlternativeName(extVal);
+		}
+
+		public static ICollection GetSubjectAlternativeNames(
+			X509Certificate cert)
+		{
+			Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.SubjectAlternativeName);
+
+			return GetAlternativeName(extVal);
+		}
+
+		private static ICollection GetAlternativeName(
+			Asn1OctetString extVal)
+		{
+			IList temp = Platform.CreateArrayList();
+
+			if (extVal != null)
+			{
+				try
+				{
+					Asn1Sequence seq = DerSequence.GetInstance(FromExtensionValue(extVal));
+
+					foreach (GeneralName genName in seq)
+					{
+                        IList list = Platform.CreateArrayList();
+						list.Add(genName.TagNo);
+
+						switch (genName.TagNo)
+						{
+							case GeneralName.EdiPartyName:
+							case GeneralName.X400Address:
+							case GeneralName.OtherName:
+								list.Add(genName.Name.ToAsn1Object());
+								break;
+							case GeneralName.DirectoryName:
+								list.Add(X509Name.GetInstance(genName.Name).ToString());
+								break;
+							case GeneralName.DnsName:
+							case GeneralName.Rfc822Name:
+							case GeneralName.UniformResourceIdentifier:
+								list.Add(((IAsn1String)genName.Name).GetString());
+								break;
+							case GeneralName.RegisteredID:
+								list.Add(DerObjectIdentifier.GetInstance(genName.Name).Id);
+								break;
+							case GeneralName.IPAddress:
+								list.Add(DerOctetString.GetInstance(genName.Name).GetOctets());
+								break;
+							default:
+								throw new IOException("Bad tag number: " + genName.TagNo);
+						}
+
+						temp.Add(list);
+					}
+				}
+				catch (Exception e)
+				{
+					throw new CertificateParsingException(e.Message);
+				}
+			}
+
+			return temp;
+		}
+	}
+}