diff --git a/crypto/src/asn1/x509/AlgorithmIdentifier.cs b/crypto/src/asn1/x509/AlgorithmIdentifier.cs
index 169a95c0a..486772c16 100644
--- a/crypto/src/asn1/x509/AlgorithmIdentifier.cs
+++ b/crypto/src/asn1/x509/AlgorithmIdentifier.cs
@@ -8,23 +8,20 @@ namespace Org.BouncyCastle.Asn1.X509
private readonly DerObjectIdentifier algorithm;
private readonly Asn1Encodable parameters;
- public static AlgorithmIdentifier GetInstance(
- Asn1TaggedObject obj,
- bool explicitly)
- {
- return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
- }
-
- public static AlgorithmIdentifier GetInstance(
- object obj)
+ public static AlgorithmIdentifier GetInstance(object obj)
{
if (obj == null)
return null;
- if (obj is AlgorithmIdentifier)
- return (AlgorithmIdentifier)obj;
+ if (obj is AlgorithmIdentifier algorithmIdentifier)
+ return algorithmIdentifier;
return new AlgorithmIdentifier(Asn1Sequence.GetInstance(obj));
}
+ public static AlgorithmIdentifier GetInstance(Asn1TaggedObject obj, bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
+
public AlgorithmIdentifier(
DerObjectIdentifier algorithm)
{
diff --git a/crypto/src/asn1/x509/AltSignatureAlgorithm.cs b/crypto/src/asn1/x509/AltSignatureAlgorithm.cs
new file mode 100644
index 000000000..0844de324
--- /dev/null
+++ b/crypto/src/asn1/x509/AltSignatureAlgorithm.cs
@@ -0,0 +1,70 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * X.509 Section 9.8.3.
+ * <br/>
+ * This extension may be used as a public-key certificate extension, a CRL extension or an AVL extension. It shall contain
+ * the algorithm identifier for the alternative digital signature algorithm used by the signer when creating an alternative
+ * digital signature and by the relying party when validating the alternative digital signature.
+ * <pre>
+ * altSignatureAlgorithm EXTENSION ::= {
+ * SYNTAX AltSignatureAlgorithm
+ * IDENTIFIED BY id-ce-altSignatureAlgorithm }
+ *
+ * AltSignatureAlgorithm ::= AlgorithmIdentifier{{SupportedAlgorithms}}
+ * </pre>
+ * When the altSignatureAlgorithm extension is included in a particular value that is an instance of a data type that
+ * supports extensions, the altSignatureValue extension shall also be included.
+ * <br/>
+ * NOTE 1 – By having a separate altSignatureAlgorithm extension, instead of having it combined with the
+ * altSignatureValue extension, the alternative digital signature algorithm is protected by the alternative signature.
+ * This extension may be flagged either as critical or as non-critical.
+ * <br/>
+ * NOTE 2 – It is recommended that it be flagged as non-critical. Flagging it as critical would require all relying parties to understand
+ * the extension and the alternative public-key algorithms
+ */
+ public class AltSignatureAlgorithm
+ : Asn1Encodable
+ {
+ private readonly AlgorithmIdentifier m_algorithm;
+
+ public static AltSignatureAlgorithm GetInstance(object obj)
+ {
+ if (obj == null)
+ return null;
+ if (obj is AltSignatureAlgorithm altSignatureAlgorithm)
+ return altSignatureAlgorithm;
+ return new AltSignatureAlgorithm(AlgorithmIdentifier.GetInstance(obj));
+ }
+
+ public static AltSignatureAlgorithm GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+ {
+ return GetInstance(AlgorithmIdentifier.GetInstance(taggedObject, declaredExplicit));
+ }
+
+ public static AltSignatureAlgorithm FromExtensions(X509Extensions extensions)
+ {
+ return GetInstance(
+ X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.AltSignatureAlgorithm));
+ }
+
+ public AltSignatureAlgorithm(AlgorithmIdentifier algorithm)
+ {
+ m_algorithm = algorithm;
+ }
+
+ public AltSignatureAlgorithm(DerObjectIdentifier algorithm, Asn1Encodable parameters)
+ {
+ m_algorithm = new AlgorithmIdentifier(algorithm, parameters);
+ }
+
+ public AlgorithmIdentifier Algorithm => m_algorithm;
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return m_algorithm.ToAsn1Object();
+ }
+ }
+}
diff --git a/crypto/src/asn1/x509/AltSignatureValue.cs b/crypto/src/asn1/x509/AltSignatureValue.cs
new file mode 100644
index 000000000..498c1d6d0
--- /dev/null
+++ b/crypto/src/asn1/x509/AltSignatureValue.cs
@@ -0,0 +1,70 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * X.509 Section 9.8.4.
+ * <br/>
+ * This extension may be used as a public-key certificate extension, a CRL extension or an AVL extension.
+ * This alternative signature shall be created by the issuer using its alternative private key, and it shall be verified using the
+ * alternative public key of the issuer.
+ * <pre>
+ * altSignatureValue EXTENSION ::= {
+ * SYNTAX AltSignatureValue
+ * IDENTIFIED BY id-ce-altSignatureValue }
+ *
+ * AltSignatureValue ::= BIT STRING
+ * </pre>
+ * This extension can only be created by a signer holding a multiple cryptographic algorithms public-key certificate. When
+ * creating the alternative digital signature on an issued public-key certificate or CRL, the signer shall use its alternative
+ * private key.
+ * <br/>
+ * The procedures for creating and validating alternative digital signatures are specified in:
+ * <ul>
+ * <li>clause 7.2.2 for public-key certificates;</li>
+ * <li>clause 7.10.3 for CRLs: and</li>
+ * <li>clause 11.4 for AVLs.</li>
+ * </ul>
+ */
+ public class AltSignatureValue
+ : Asn1Encodable
+ {
+ private readonly DerBitString m_signature;
+
+ public static AltSignatureValue GetInstance(object obj)
+ {
+ if (obj == null)
+ return null;
+ if (obj is AltSignatureValue altSignatureValue)
+ return altSignatureValue;
+ return new AltSignatureValue(DerBitString.GetInstance(obj));
+ }
+
+ public static AltSignatureValue GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+ {
+ return GetInstance(DerBitString.GetInstance(taggedObject, declaredExplicit));
+ }
+
+ public static AltSignatureValue FromExtensions(X509Extensions extensions)
+ {
+ return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.AltSignatureValue));
+ }
+
+ private AltSignatureValue(DerBitString signature)
+ {
+ m_signature = signature;
+ }
+
+ public AltSignatureValue(byte[] signature)
+ {
+ m_signature = new DerBitString(signature);
+ }
+
+ public DerBitString Signature => m_signature;
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return m_signature;
+ }
+ }
+}
diff --git a/crypto/src/asn1/x509/SubjectAltPublicKeyInfo.cs b/crypto/src/asn1/x509/SubjectAltPublicKeyInfo.cs
new file mode 100644
index 000000000..4fe165898
--- /dev/null
+++ b/crypto/src/asn1/x509/SubjectAltPublicKeyInfo.cs
@@ -0,0 +1,84 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.X509
+{
+ /**
+ * X.509 Section 9.8.2.
+ * <br/>
+ * This public-key certificate extension, when present, shall contain the subject’s alternative public key information
+ * <pre>
+ * subjectAltPublicKeyInfo EXTENSION ::= {
+ * SYNTAX SubjectAltPublicKeyInfo
+ * IDENTIFIED BY id-ce-subjectAltPublicKeyInfo }
+ *
+ * SubjectAltPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier{{SupportedAlgorithms}},
+ * subjectAltPublicKey BIT STRING }
+ * </pre>
+ * The SubjectAltPublicKeyInfo data type has the following components:
+ * <ul>
+ * <li>the algorithm subcomponent, which shall hold the algorithm that this public key is an instance of</li>
+ * <li>the subjectAltPublicKey subcomponent, which shall hold the alternative public key</li>
+ * </ul>
+ * This extension may be flagged as critical or as non-critical.
+ * <br/>
+ * NOTE – It is recommended that it be flagged as non-critical. Flagging it as critical would require relying parties to understand this
+ * extension and the alternative public-key algorithm.
+ */
+ public class SubjectAltPublicKeyInfo
+ : Asn1Encodable
+ {
+ private readonly AlgorithmIdentifier m_algorithm;
+ private readonly DerBitString m_subjectAltPublicKey;
+
+ public static SubjectAltPublicKeyInfo GetInstance(object obj)
+ {
+ if (obj == null)
+ return null;
+ if (obj is SubjectAltPublicKeyInfo subjectAltPublicKeyInfo)
+ return subjectAltPublicKeyInfo;
+ return new SubjectAltPublicKeyInfo(Asn1Sequence.GetInstance(obj));
+ }
+
+ public static SubjectAltPublicKeyInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+ }
+
+ public static SubjectAltPublicKeyInfo FromExtensions(X509Extensions extensions)
+ {
+ return GetInstance(
+ X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.SubjectAltPublicKeyInfo));
+ }
+
+ private SubjectAltPublicKeyInfo(Asn1Sequence seq)
+ {
+ if (seq.Count != 2)
+ throw new ArgumentException("extension should contain only 2 elements");
+
+ m_algorithm = AlgorithmIdentifier.GetInstance(seq[0]);
+ m_subjectAltPublicKey = DerBitString.GetInstance(seq[1]);
+ }
+
+ public SubjectAltPublicKeyInfo(AlgorithmIdentifier algorithm, DerBitString subjectAltPublicKey)
+ {
+ m_algorithm = algorithm;
+ m_subjectAltPublicKey = subjectAltPublicKey;
+ }
+
+ public SubjectAltPublicKeyInfo(SubjectPublicKeyInfo subjectPublicKeyInfo)
+ {
+ m_algorithm = subjectPublicKeyInfo.AlgorithmID;
+ m_subjectAltPublicKey = subjectPublicKeyInfo.PublicKeyData;
+ }
+
+ public AlgorithmIdentifier Algorithm => Algorithm;
+
+ public DerBitString SubjectAltPublicKey => m_subjectAltPublicKey;
+
+ public override Asn1Object ToAsn1Object()
+ {
+ return new DerSequence(m_algorithm, m_subjectAltPublicKey);
+ }
+ }
+}
diff --git a/crypto/src/asn1/x509/X509Extensions.cs b/crypto/src/asn1/x509/X509Extensions.cs
index aa5205800..62291a829 100644
--- a/crypto/src/asn1/x509/X509Extensions.cs
+++ b/crypto/src/asn1/x509/X509Extensions.cs
@@ -169,6 +169,21 @@ namespace Org.BouncyCastle.Asn1.X509
*/
public static readonly DerObjectIdentifier ExpiredCertsOnCrl = new DerObjectIdentifier("2.5.29.60");
+ /**
+ * the subject’s alternative public key information
+ */
+ public static readonly DerObjectIdentifier SubjectAltPublicKeyInfo = new DerObjectIdentifier("2.5.29.72");
+
+ /**
+ * the algorithm identifier for the alternative digital signature algorithm.
+ */
+ public static readonly DerObjectIdentifier AltSignatureAlgorithm = new DerObjectIdentifier("2.5.29.73");
+
+ /**
+ * alternative signature shall be created by the issuer using its alternative private key.
+ */
+ public static readonly DerObjectIdentifier AltSignatureValue = new DerObjectIdentifier("2.5.29.74");
+
private readonly Dictionary<DerObjectIdentifier, X509Extension> m_extensions =
new Dictionary<DerObjectIdentifier, X509Extension>();
private readonly List<DerObjectIdentifier> m_ordering;
|