diff options
author | mw <megan@cryptoworkshop.com> | 2021-09-01 16:00:23 +1000 |
---|---|---|
committer | mw <megan@cryptoworkshop.com> | 2021-09-01 16:00:23 +1000 |
commit | 0b0f03c598b558c7acf79a969315a8d2e0aa1f1b (patch) | |
tree | eb8091bd81be5d8225a38ac8947594d7f694a3c6 /crypto/src/asn1 | |
parent | fixed typos (diff) | |
download | BouncyCastle.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.cs | 195 |
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); } } } |