diff --git a/crypto/src/asn1/DerUTF8String.cs b/crypto/src/asn1/DerUTF8String.cs
index a9f35abda..965a8ebf8 100644
--- a/crypto/src/asn1/DerUTF8String.cs
+++ b/crypto/src/asn1/DerUTF8String.cs
@@ -69,6 +69,21 @@ namespace Org.BouncyCastle.Asn1
return (DerUtf8String)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
}
+ public static DerUtf8String GetOptional(Asn1Encodable element)
+ {
+ if (element == null)
+ throw new ArgumentNullException(nameof(element));
+ if (element is DerUtf8String derUtf8String)
+ return derUtf8String;
+ if (element is IAsn1Convertible asn1Convertible && !(element is Asn1Object))
+ {
+ Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
+ if (asn1Object is DerUtf8String converted)
+ return converted;
+ }
+ return null;
+ }
+
private readonly byte[] m_contents;
public DerUtf8String(string str)
diff --git a/crypto/src/asn1/crmf/AttributeTypeAndValue.cs b/crypto/src/asn1/crmf/AttributeTypeAndValue.cs
index e7587896a..a9899d2f7 100644
--- a/crypto/src/asn1/crmf/AttributeTypeAndValue.cs
+++ b/crypto/src/asn1/crmf/AttributeTypeAndValue.cs
@@ -1,56 +1,51 @@
using System;
-using Org.BouncyCastle.Utilities;
-
namespace Org.BouncyCastle.Asn1.Crmf
{
public class AttributeTypeAndValue
: Asn1Encodable
{
- private readonly DerObjectIdentifier type;
- private readonly Asn1Encodable value;
-
- private AttributeTypeAndValue(Asn1Sequence seq)
+ public static AttributeTypeAndValue GetInstance(object obj)
{
- type = (DerObjectIdentifier)seq[0];
- value = (Asn1Encodable)seq[1];
+ if (obj == null)
+ return null;
+ if (obj is AttributeTypeAndValue attributeTypeAndValue)
+ return attributeTypeAndValue;
+ return new AttributeTypeAndValue(Asn1Sequence.GetInstance(obj));
}
- public static AttributeTypeAndValue GetInstance(object obj)
+ public static AttributeTypeAndValue GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
- if (obj is AttributeTypeAndValue)
- return (AttributeTypeAndValue)obj;
+ return new AttributeTypeAndValue(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+ }
- if (obj is Asn1Sequence)
- return new AttributeTypeAndValue((Asn1Sequence)obj);
+ private readonly DerObjectIdentifier m_type;
+ private readonly Asn1Encodable m_value;
- throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj");
+ private AttributeTypeAndValue(Asn1Sequence seq)
+ {
+ int count = seq.Count;
+ if (count != 2)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+ m_type = DerObjectIdentifier.GetInstance(seq[0]);
+ m_value = seq[1];
}
- public AttributeTypeAndValue(
- string oid,
- Asn1Encodable value)
+ public AttributeTypeAndValue(string oid, Asn1Encodable value)
: this(new DerObjectIdentifier(oid), value)
{
}
- public AttributeTypeAndValue(
- DerObjectIdentifier type,
- Asn1Encodable value)
+ public AttributeTypeAndValue(DerObjectIdentifier type, Asn1Encodable value)
{
- this.type = type;
- this.value = value;
+ m_type = type ?? throw new ArgumentNullException(nameof(type));
+ m_value = value ?? throw new ArgumentNullException(nameof(value));
}
- public virtual DerObjectIdentifier Type
- {
- get { return type; }
- }
+ public virtual DerObjectIdentifier Type => m_type;
- public virtual Asn1Encodable Value
- {
- get { return value; }
- }
+ public virtual Asn1Encodable Value => m_value;
/**
* <pre>
@@ -60,9 +55,6 @@ namespace Org.BouncyCastle.Asn1.Crmf
* </pre>
* @return a basic ASN.1 object representation.
*/
- public override Asn1Object ToAsn1Object()
- {
- return new DerSequence(type, value);
- }
+ public override Asn1Object ToAsn1Object() => new DerSequence(m_type, m_value);
}
}
diff --git a/crypto/src/asn1/crmf/CertId.cs b/crypto/src/asn1/crmf/CertId.cs
index c63c21ca8..c9f66b065 100644
--- a/crypto/src/asn1/crmf/CertId.cs
+++ b/crypto/src/asn1/crmf/CertId.cs
@@ -1,4 +1,6 @@
-using Org.BouncyCastle.Asn1.X509;
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.Crmf
{
@@ -9,8 +11,8 @@ namespace Org.BouncyCastle.Asn1.Crmf
{
if (obj == null)
return null;
- if (obj is CertId certID)
- return certID;
+ if (obj is CertId certId)
+ return certId;
return new CertId(Asn1Sequence.GetInstance(obj));
}
@@ -24,10 +26,20 @@ namespace Org.BouncyCastle.Asn1.Crmf
private CertId(Asn1Sequence seq)
{
+ int count = seq.Count;
+ if (count != 2)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
m_issuer = GeneralName.GetInstance(seq[0]);
m_serialNumber = DerInteger.GetInstance(seq[1]);
}
+ public CertId(GeneralName issuer, DerInteger serialNumber)
+ {
+ m_issuer = issuer ?? throw new ArgumentNullException(nameof(issuer));
+ m_serialNumber = serialNumber ?? throw new ArgumentNullException(nameof(serialNumber));
+ }
+
public virtual GeneralName Issuer => m_issuer;
public virtual DerInteger SerialNumber => m_serialNumber;
diff --git a/crypto/src/asn1/crmf/CertReqMessages.cs b/crypto/src/asn1/crmf/CertReqMessages.cs
index d49b90fe3..fc01fb99d 100644
--- a/crypto/src/asn1/crmf/CertReqMessages.cs
+++ b/crypto/src/asn1/crmf/CertReqMessages.cs
@@ -1,49 +1,42 @@
-using System;
-
-using Org.BouncyCastle.Utilities;
-
namespace Org.BouncyCastle.Asn1.Crmf
{
public class CertReqMessages
: Asn1Encodable
{
- private readonly Asn1Sequence content;
-
- private CertReqMessages(Asn1Sequence seq)
+ public static CertReqMessages GetInstance(object obj)
{
- content = seq;
+ if (obj == null)
+ return null;
+ if (obj is CertReqMessages certReqMessages)
+ return certReqMessages;
+ return new CertReqMessages(Asn1Sequence.GetInstance(obj));
}
- public static CertReqMessages GetInstance(object obj)
+ public static CertReqMessages GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
- if (obj is CertReqMessages)
- return (CertReqMessages)obj;
-
- if (obj is Asn1Sequence)
- return new CertReqMessages((Asn1Sequence)obj);
-
- throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj");
+ return new CertReqMessages(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
}
- public CertReqMessages(params CertReqMsg[] msgs)
+ private readonly Asn1Sequence m_content;
+
+ private CertReqMessages(Asn1Sequence seq)
{
- content = new DerSequence(msgs);
+ m_content = seq;
}
- public virtual CertReqMsg[] ToCertReqMsgArray()
+ public CertReqMessages(params CertReqMsg[] msgs)
{
- return content.MapElements(CertReqMsg.GetInstance);
+ m_content = new DerSequence(msgs);
}
+ public virtual CertReqMsg[] ToCertReqMsgArray() => m_content.MapElements(CertReqMsg.GetInstance);
+
/**
* <pre>
* CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg
* </pre>
* @return a basic ASN.1 object representation.
*/
- public override Asn1Object ToAsn1Object()
- {
- return content;
- }
+ public override Asn1Object ToAsn1Object() => m_content;
}
}
diff --git a/crypto/src/asn1/crmf/CertReqMsg.cs b/crypto/src/asn1/crmf/CertReqMsg.cs
index 1832a34cc..5e56f68c9 100644
--- a/crypto/src/asn1/crmf/CertReqMsg.cs
+++ b/crypto/src/asn1/crmf/CertReqMsg.cs
@@ -25,21 +25,18 @@ namespace Org.BouncyCastle.Asn1.Crmf
private CertReqMsg(Asn1Sequence seq)
{
- m_certReq = CertRequest.GetInstance(seq[0]);
+ int count = seq.Count;
+ if (count < 1 || count > 3)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
- for (int pos = 1; pos < seq.Count; ++pos)
- {
- object o = seq[pos];
+ int pos = 0;
- if (o is Asn1TaggedObject || o is ProofOfPossession)
- {
- m_pop = ProofOfPossession.GetInstance(o);
- }
- else
- {
- m_regInfo = Asn1Sequence.GetInstance(o);
- }
- }
+ m_certReq = CertRequest.GetInstance(seq[pos++]);
+ m_pop = Asn1Utilities.ReadOptional(seq, ref pos, ProofOfPossession.GetOptional);
+ m_regInfo = Asn1Utilities.ReadOptional(seq, ref pos, Asn1Sequence.GetOptional);
+
+ if (pos != count)
+ throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
}
/**
@@ -50,13 +47,9 @@ namespace Org.BouncyCastle.Asn1.Crmf
*/
public CertReqMsg(CertRequest certReq, ProofOfPossession popo, AttributeTypeAndValue[] regInfo)
{
- this.m_certReq = certReq ?? throw new ArgumentNullException(nameof(certReq));
- this.m_pop = popo;
-
- if (regInfo != null)
- {
- this.m_regInfo = new DerSequence(regInfo);
- }
+ m_certReq = certReq ?? throw new ArgumentNullException(nameof(certReq));
+ m_pop = popo;
+ m_regInfo = regInfo == null ? null : new DerSequence(regInfo);
}
public virtual CertRequest CertReq => m_certReq;
@@ -81,7 +74,7 @@ namespace Org.BouncyCastle.Asn1.Crmf
*/
public override Asn1Object ToAsn1Object()
{
- Asn1EncodableVector v = new Asn1EncodableVector(2);
+ Asn1EncodableVector v = new Asn1EncodableVector(3);
v.Add(m_certReq);
v.AddOptional(m_pop, m_regInfo);
return new DerSequence(v);
diff --git a/crypto/src/asn1/crmf/CertRequest.cs b/crypto/src/asn1/crmf/CertRequest.cs
index bf6182f25..dea7ea23c 100644
--- a/crypto/src/asn1/crmf/CertRequest.cs
+++ b/crypto/src/asn1/crmf/CertRequest.cs
@@ -1,68 +1,61 @@
using System;
-using Org.BouncyCastle.Crmf;
namespace Org.BouncyCastle.Asn1.Crmf
{
public class CertRequest
: Asn1Encodable
{
- private readonly DerInteger certReqId;
- private readonly CertTemplate certTemplate;
- private readonly Controls controls;
+ public static CertRequest GetInstance(object obj)
+ {
+ if (obj == null)
+ return null;
+ if (obj is CertRequest certRequest)
+ return certRequest;
+ return new CertRequest(Asn1Sequence.GetInstance(obj));
+ }
- private CertRequest(Asn1Sequence seq)
+ public static CertRequest GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
- certReqId = DerInteger.GetInstance(seq[0]);
- certTemplate = CertTemplate.GetInstance(seq[1]);
- if (seq.Count > 2)
- {
- controls = Controls.GetInstance(seq[2]);
- }
+ return new CertRequest(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
}
- public static CertRequest GetInstance(object obj)
+ private readonly DerInteger m_certReqId;
+ private readonly CertTemplate m_certTemplate;
+ private readonly Controls m_controls;
+
+ private CertRequest(Asn1Sequence seq)
{
- if (obj is CertRequest)
- return (CertRequest)obj;
+ int count = seq.Count;
+ if (count < 2 || count > 3)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
- if (obj != null)
- return new CertRequest(Asn1Sequence.GetInstance(obj));
+ int pos = 0;
- return null;
+ m_certReqId = DerInteger.GetInstance(seq[pos++]);
+ m_certTemplate = CertTemplate.GetInstance(seq[pos++]);
+ m_controls = Asn1Utilities.ReadOptional(seq, ref pos, Controls.GetOptional);
+
+ if (pos != count)
+ throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
}
- public CertRequest(
- int certReqId,
- CertTemplate certTemplate,
- Controls controls)
+ public CertRequest(int certReqId, CertTemplate certTemplate, Controls controls)
: this(new DerInteger(certReqId), certTemplate, controls)
{
}
- public CertRequest(
- DerInteger certReqId,
- CertTemplate certTemplate,
- Controls controls)
+ public CertRequest(DerInteger certReqId, CertTemplate certTemplate, Controls controls)
{
- this.certReqId = certReqId;
- this.certTemplate = certTemplate;
- this.controls = controls;
+ m_certReqId = certReqId ?? throw new ArgumentNullException(nameof(certReqId));
+ m_certTemplate = certTemplate ?? throw new ArgumentNullException(nameof(certTemplate));
+ m_controls = controls;
}
- public virtual DerInteger CertReqID
- {
- get { return certReqId; }
- }
+ public virtual DerInteger CertReqID => m_certReqId;
- public virtual CertTemplate CertTemplate
- {
- get { return certTemplate; }
- }
+ public virtual CertTemplate CertTemplate => m_certTemplate;
- public virtual Controls Controls
- {
- get { return controls; }
- }
+ public virtual Controls Controls => m_controls;
/**
* <pre>
@@ -75,8 +68,9 @@ namespace Org.BouncyCastle.Asn1.Crmf
*/
public override Asn1Object ToAsn1Object()
{
- Asn1EncodableVector v = new Asn1EncodableVector(certReqId, certTemplate);
- v.AddOptional(controls);
+ Asn1EncodableVector v = new Asn1EncodableVector(3);
+ v.Add(m_certReqId, m_certTemplate);
+ v.AddOptional(m_controls);
return new DerSequence(v);
}
}
diff --git a/crypto/src/asn1/crmf/CertTemplate.cs b/crypto/src/asn1/crmf/CertTemplate.cs
index f731ac12e..62227808c 100644
--- a/crypto/src/asn1/crmf/CertTemplate.cs
+++ b/crypto/src/asn1/crmf/CertTemplate.cs
@@ -7,123 +7,77 @@ namespace Org.BouncyCastle.Asn1.Crmf
public class CertTemplate
: Asn1Encodable
{
- private readonly Asn1Sequence seq;
-
- private readonly DerInteger version;
- private readonly DerInteger serialNumber;
- private readonly AlgorithmIdentifier signingAlg;
- private readonly X509Name issuer;
- private readonly OptionalValidity validity;
- private readonly X509Name subject;
- private readonly SubjectPublicKeyInfo publicKey;
- private readonly DerBitString issuerUID;
- private readonly DerBitString subjectUID;
- private readonly X509Extensions extensions;
-
- private CertTemplate(Asn1Sequence seq)
+ public static CertTemplate GetInstance(object obj)
{
- this.seq = seq;
-
- foreach (Asn1TaggedObject tObj in seq)
- {
- switch (tObj.TagNo)
- {
- case 0:
- version = DerInteger.GetInstance(tObj, false);
- break;
- case 1:
- serialNumber = DerInteger.GetInstance(tObj, false);
- break;
- case 2:
- signingAlg = AlgorithmIdentifier.GetInstance(tObj, false);
- break;
- case 3:
- issuer = X509Name.GetInstance(tObj, true); // CHOICE
- break;
- case 4:
- validity = OptionalValidity.GetInstance(Asn1Sequence.GetInstance(tObj, false));
- break;
- case 5:
- subject = X509Name.GetInstance(tObj, true); // CHOICE
- break;
- case 6:
- publicKey = SubjectPublicKeyInfo.GetInstance(tObj, false);
- break;
- case 7:
- issuerUID = DerBitString.GetInstance(tObj, false);
- break;
- case 8:
- subjectUID = DerBitString.GetInstance(tObj, false);
- break;
- case 9:
- extensions = X509Extensions.GetInstance(tObj, false);
- break;
- default:
- throw new ArgumentException("unknown tag: " + tObj.TagNo, "seq");
- }
- }
+ if (obj == null)
+ return null;
+ if (obj is CertTemplate certTemplate)
+ return certTemplate;
+ return new CertTemplate(Asn1Sequence.GetInstance(obj));
}
- public static CertTemplate GetInstance(object obj)
+ public static CertTemplate GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
- if (obj is CertTemplate)
- return (CertTemplate)obj;
+ return new CertTemplate(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+ }
- if (obj != null)
- return new CertTemplate(Asn1Sequence.GetInstance(obj));
+ private readonly Asn1Sequence m_seq;
- return null;
- }
+ private readonly DerInteger m_version;
+ private readonly DerInteger m_serialNumber;
+ private readonly AlgorithmIdentifier m_signingAlg;
+ private readonly X509Name m_issuer;
+ private readonly OptionalValidity m_validity;
+ private readonly X509Name m_subject;
+ private readonly SubjectPublicKeyInfo m_publicKey;
+ private readonly DerBitString m_issuerUID;
+ private readonly DerBitString m_subjectUID;
+ private readonly X509Extensions m_extensions;
- public virtual int Version
+ private CertTemplate(Asn1Sequence seq)
{
- get { return version.IntValueExact; }
+ int count = seq.Count;
+ if (count < 0 || count > 10)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+ int pos = 0;
+
+ m_version = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, false, DerInteger.GetInstance);
+ m_serialNumber = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, false, DerInteger.GetInstance);
+ m_signingAlg = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, false, AlgorithmIdentifier.GetInstance);
+ m_issuer = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 3, true, X509Name.GetInstance); // CHOICE Name
+ m_validity = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 4, false, OptionalValidity.GetInstance);
+ m_subject = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 5, true, X509Name.GetInstance); // CHOICE Name
+ m_publicKey = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 6, false, SubjectPublicKeyInfo.GetInstance);
+ m_issuerUID = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 7, false, DerBitString.GetInstance);
+ m_subjectUID = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 8, false, DerBitString.GetInstance);
+ m_extensions = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 9, false, X509Extensions.GetInstance);
+
+ if (pos != count)
+ throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
+
+ m_seq = seq;
}
- public virtual DerInteger SerialNumber
- {
- get { return serialNumber; }
- }
+ public virtual int Version => m_version.IntValueExact;
- public virtual AlgorithmIdentifier SigningAlg
- {
- get { return signingAlg; }
- }
+ public virtual DerInteger SerialNumber => m_serialNumber;
- public virtual X509Name Issuer
- {
- get { return issuer; }
- }
+ public virtual AlgorithmIdentifier SigningAlg => m_signingAlg;
- public virtual OptionalValidity Validity
- {
- get { return validity; }
- }
+ public virtual X509Name Issuer => m_issuer;
- public virtual X509Name Subject
- {
- get { return subject; }
- }
+ public virtual OptionalValidity Validity => m_validity;
- public virtual SubjectPublicKeyInfo PublicKey
- {
- get { return publicKey; }
- }
+ public virtual X509Name Subject => m_subject;
- public virtual DerBitString IssuerUID
- {
- get { return issuerUID; }
- }
+ public virtual SubjectPublicKeyInfo PublicKey => m_publicKey;
- public virtual DerBitString SubjectUID
- {
- get { return subjectUID; }
- }
+ public virtual DerBitString IssuerUID => m_issuerUID;
- public virtual X509Extensions Extensions
- {
- get { return extensions; }
- }
+ public virtual DerBitString SubjectUID => m_subjectUID;
+
+ public virtual X509Extensions Extensions => m_extensions;
/**
* <pre>
@@ -141,9 +95,6 @@ namespace Org.BouncyCastle.Asn1.Crmf
* </pre>
* @return a basic ASN.1 object representation.
*/
- public override Asn1Object ToAsn1Object()
- {
- return seq;
- }
+ public override Asn1Object ToAsn1Object() => m_seq;
}
}
diff --git a/crypto/src/asn1/crmf/Controls.cs b/crypto/src/asn1/crmf/Controls.cs
index ac568d741..12954f5e8 100644
--- a/crypto/src/asn1/crmf/Controls.cs
+++ b/crypto/src/asn1/crmf/Controls.cs
@@ -1,40 +1,50 @@
using System;
-using System.Text;
-
-using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.Crmf
{
public class Controls
: Asn1Encodable
{
- private readonly Asn1Sequence content;
+ public static Controls GetInstance(object obj)
+ {
+ if (obj == null)
+ return null;
+ if (obj is Controls controls)
+ return controls;
+ return new Controls(Asn1Sequence.GetInstance(obj));
+ }
- private Controls(Asn1Sequence seq)
+ public static Controls GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
- content = seq;
+ return new Controls(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
}
- public static Controls GetInstance(object obj)
+ public static Controls GetOptional(Asn1Encodable element)
{
- if (obj is Controls)
- return (Controls)obj;
+ if (element == null)
+ throw new ArgumentNullException(nameof(element));
+ if (element is Controls controls)
+ return controls;
+ Asn1Sequence asn1Sequence = Asn1Sequence.GetOptional(element);
+ if (asn1Sequence != null)
+ return new Controls(asn1Sequence);
+ return null;
+ }
- if (obj is Asn1Sequence)
- return new Controls((Asn1Sequence)obj);
+ private readonly Asn1Sequence m_content;
- throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj");
+ private Controls(Asn1Sequence seq)
+ {
+ m_content = seq;
}
public Controls(params AttributeTypeAndValue[] atvs)
{
- content = new DerSequence(atvs);
+ m_content = new DerSequence(atvs);
}
- public virtual AttributeTypeAndValue[] ToAttributeTypeAndValueArray()
- {
- return content.MapElements(AttributeTypeAndValue.GetInstance);
- }
+ public virtual AttributeTypeAndValue[] ToAttributeTypeAndValueArray() =>
+ m_content.MapElements(AttributeTypeAndValue.GetInstance);
/**
* <pre>
@@ -42,9 +52,6 @@ namespace Org.BouncyCastle.Asn1.Crmf
* </pre>
* @return a basic ASN.1 object representation.
*/
- public override Asn1Object ToAsn1Object()
- {
- return content;
- }
+ public override Asn1Object ToAsn1Object() => m_content;
}
}
diff --git a/crypto/src/asn1/crmf/EncKeyWithID.cs b/crypto/src/asn1/crmf/EncKeyWithID.cs
index 67c16605a..272c38949 100644
--- a/crypto/src/asn1/crmf/EncKeyWithID.cs
+++ b/crypto/src/asn1/crmf/EncKeyWithID.cs
@@ -8,78 +8,74 @@ namespace Org.BouncyCastle.Asn1.Crmf
public class EncKeyWithID
: Asn1Encodable
{
- private readonly PrivateKeyInfo privKeyInfo;
- private readonly Asn1Encodable identifier;
-
public static EncKeyWithID GetInstance(object obj)
{
- if (obj is EncKeyWithID)
- return (EncKeyWithID)obj;
+ if (obj == null)
+ return null;
+ if (obj is EncKeyWithID encKeyWithID)
+ return encKeyWithID;
+ return new EncKeyWithID(Asn1Sequence.GetInstance(obj));
+ }
+
+ public static EncKeyWithID GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+ {
+ return new EncKeyWithID(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+ }
- if (obj != null)
- return new EncKeyWithID(Asn1Sequence.GetInstance(obj));
+ private static Asn1Encodable GetOptionalChoice(Asn1Encodable element)
+ {
+ var _string = DerUtf8String.GetOptional(element);
+ if (_string != null)
+ return _string;
- return null;
+ return GeneralName.GetInstance(element);
}
+ private readonly PrivateKeyInfo m_privKeyInfo;
+ private readonly Asn1Encodable m_identifier;
+
private EncKeyWithID(Asn1Sequence seq)
{
- this.privKeyInfo = PrivateKeyInfo.GetInstance(seq[0]);
+ int count = seq.Count;
+ if (count < 1 || count > 2)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
- if (seq.Count > 1)
- {
- if (!(seq[1] is DerUtf8String))
- {
- this.identifier = GeneralName.GetInstance(seq[1]);
- }
- else
- {
- this.identifier = seq[1];
- }
- }
- else
+ m_privKeyInfo = PrivateKeyInfo.GetInstance(seq[0]);
+
+ if (count > 1)
{
- this.identifier = null;
+ m_identifier = GetOptionalChoice(seq[1]);
}
}
+ private EncKeyWithID(PrivateKeyInfo privKeyInfo, Asn1Encodable identifier)
+ {
+ m_privKeyInfo = privKeyInfo ?? throw new ArgumentNullException(nameof(privKeyInfo));
+ m_identifier = identifier;
+ }
+
public EncKeyWithID(PrivateKeyInfo privKeyInfo)
+ : this(privKeyInfo, (Asn1Encodable)null)
{
- this.privKeyInfo = privKeyInfo;
- this.identifier = null;
}
public EncKeyWithID(PrivateKeyInfo privKeyInfo, DerUtf8String str)
+ : this(privKeyInfo, (Asn1Encodable)str)
{
- this.privKeyInfo = privKeyInfo;
- this.identifier = str;
}
public EncKeyWithID(PrivateKeyInfo privKeyInfo, GeneralName generalName)
+ : this(privKeyInfo, (Asn1Encodable)generalName)
{
- this.privKeyInfo = privKeyInfo;
- this.identifier = generalName;
}
- public virtual PrivateKeyInfo PrivateKey
- {
- get { return privKeyInfo; }
- }
+ public virtual PrivateKeyInfo PrivateKey => m_privKeyInfo;
- public virtual bool HasIdentifier
- {
- get { return identifier != null; }
- }
+ public virtual bool HasIdentifier => m_identifier != null;
- public virtual bool IsIdentifierUtf8String
- {
- get { return identifier is DerUtf8String; }
- }
+ public virtual bool IsIdentifierUtf8String => m_identifier is DerUtf8String;
- public virtual Asn1Encodable Identifier
- {
- get { return identifier; }
- }
+ public virtual Asn1Encodable Identifier => m_identifier;
/**
* <pre>
@@ -95,9 +91,9 @@ namespace Org.BouncyCastle.Asn1.Crmf
*/
public override Asn1Object ToAsn1Object()
{
- Asn1EncodableVector v = new Asn1EncodableVector(privKeyInfo);
- v.AddOptional(identifier);
- return new DerSequence(v);
+ return m_identifier == null
+ ? new DerSequence(m_privKeyInfo)
+ : new DerSequence(m_privKeyInfo, m_identifier);
}
}
}
diff --git a/crypto/src/asn1/crmf/EncryptedKey.cs b/crypto/src/asn1/crmf/EncryptedKey.cs
index d4ff250c5..62c475f5d 100644
--- a/crypto/src/asn1/crmf/EncryptedKey.cs
+++ b/crypto/src/asn1/crmf/EncryptedKey.cs
@@ -16,6 +16,11 @@ namespace Org.BouncyCastle.Asn1.Crmf
return new EncryptedKey(EncryptedValue.GetInstance(obj));
}
+ public static EncryptedKey GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+ {
+ return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance);
+ }
+
private readonly EnvelopedData m_envelopedData;
private readonly EncryptedValue m_encryptedValue;
diff --git a/crypto/src/asn1/crmf/EncryptedValue.cs b/crypto/src/asn1/crmf/EncryptedValue.cs
index 05a96fd37..756c20bd0 100644
--- a/crypto/src/asn1/crmf/EncryptedValue.cs
+++ b/crypto/src/asn1/crmf/EncryptedValue.cs
@@ -9,13 +9,16 @@ namespace Org.BouncyCastle.Asn1.Crmf
{
public static EncryptedValue GetInstance(object obj)
{
+ if (obj == null)
+ return null;
if (obj is EncryptedValue encryptedValue)
return encryptedValue;
+ return new EncryptedValue(Asn1Sequence.GetInstance(obj));
+ }
- if (obj != null)
- return new EncryptedValue(Asn1Sequence.GetInstance(obj));
-
- return null;
+ public static EncryptedValue GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+ {
+ return new EncryptedValue(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
}
private readonly AlgorithmIdentifier m_intendedAlg;
diff --git a/crypto/src/asn1/crmf/OptionalValidity.cs b/crypto/src/asn1/crmf/OptionalValidity.cs
index 722705232..290d1905e 100644
--- a/crypto/src/asn1/crmf/OptionalValidity.cs
+++ b/crypto/src/asn1/crmf/OptionalValidity.cs
@@ -7,48 +7,51 @@ namespace Org.BouncyCastle.Asn1.Crmf
public class OptionalValidity
: Asn1Encodable
{
- private readonly Time notBefore;
- private readonly Time notAfter;
-
- private OptionalValidity(Asn1Sequence seq)
- {
- foreach (Asn1TaggedObject tObj in seq)
- {
- if (tObj.TagNo == 0)
- {
- notBefore = Time.GetInstance(tObj, true);
- }
- else
- {
- notAfter = Time.GetInstance(tObj, true);
- }
- }
- }
-
public static OptionalValidity GetInstance(object obj)
{
- if (obj == null || obj is OptionalValidity)
- return (OptionalValidity)obj;
-
+ if (obj == null)
+ return null;
+ if (obj is OptionalValidity optionalValidity)
+ return optionalValidity;
return new OptionalValidity(Asn1Sequence.GetInstance(obj));
}
- public OptionalValidity(Time notBefore, Time notAfter)
+ public static OptionalValidity GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
- this.notBefore = notBefore;
- this.notAfter = notAfter;
+ return new OptionalValidity(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
}
- public virtual Time NotBefore
+ private readonly Time m_notBefore;
+ private readonly Time m_notAfter;
+
+ private OptionalValidity(Asn1Sequence seq)
{
- get { return notBefore; }
+ // TODO Enforce "at least one MUST be present"?
+
+ int count = seq.Count;
+ if (count < 0 || count > 2)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+ int pos = 0;
+
+ m_notBefore = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, Time.GetInstance);
+ m_notAfter = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, Time.GetInstance);
+
+ if (pos != count)
+ throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
}
- public virtual Time NotAfter
+ public OptionalValidity(Time notBefore, Time notAfter)
{
- get { return notAfter; }
+ // TODO Enforce "at least one MUST be present"?
+ m_notBefore = notBefore;
+ m_notAfter = notAfter;
}
+ public virtual Time NotBefore => m_notBefore;
+
+ public virtual Time NotAfter => m_notAfter;
+
/**
* <pre>
* OptionalValidity ::= SEQUENCE {
@@ -60,8 +63,8 @@ namespace Org.BouncyCastle.Asn1.Crmf
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector v = new Asn1EncodableVector(2);
- v.AddOptionalTagged(true, 0, notBefore);
- v.AddOptionalTagged(true, 1, notAfter);
+ v.AddOptionalTagged(true, 0, m_notBefore);
+ v.AddOptionalTagged(true, 1, m_notAfter);
return new DerSequence(v);
}
}
diff --git a/crypto/src/asn1/crmf/PKIArchiveOptions.cs b/crypto/src/asn1/crmf/PKIArchiveOptions.cs
index 85815c5db..7f756b39a 100644
--- a/crypto/src/asn1/crmf/PKIArchiveOptions.cs
+++ b/crypto/src/asn1/crmf/PKIArchiveOptions.cs
@@ -11,71 +11,87 @@ namespace Org.BouncyCastle.Asn1.Crmf
public const int keyGenParameters = 1;
public const int archiveRemGenPrivKey = 2;
- private readonly Asn1Encodable value;
-
public static PkiArchiveOptions GetInstance(object obj)
{
- if (obj is PkiArchiveOptions pkiArchiveOptions)
- return pkiArchiveOptions;
+ if (obj == null)
+ return null;
+
+ if (obj is Asn1Encodable element)
+ {
+ var result = GetOptional(element);
+ if (result != null)
+ return result;
+ }
- if (obj is Asn1TaggedObject taggedObject)
- return new PkiArchiveOptions(Asn1Utilities.CheckContextTagClass(taggedObject));
+ throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj));
+ }
- throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj");
+ public static PkiArchiveOptions GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+ {
+ return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance);
}
- private PkiArchiveOptions(Asn1TaggedObject tagged)
+ public static PkiArchiveOptions GetOptional(Asn1Encodable element)
{
- switch (tagged.TagNo)
+ if (element == null)
+ throw new ArgumentNullException(nameof(element));
+ if (element is PkiArchiveOptions pkiArchiveOptions)
+ return pkiArchiveOptions;
+ if (element is Asn1TaggedObject taggedObject)
{
- case encryptedPrivKey:
- value = EncryptedKey.GetInstance(tagged.GetExplicitBaseObject());
- break;
- case keyGenParameters:
- value = Asn1OctetString.GetInstance(tagged, false);
- break;
- case archiveRemGenPrivKey:
- value = DerBoolean.GetInstance(tagged, false);
- break;
- default:
- throw new ArgumentException("unknown tag number: " + tagged.TagNo, "tagged");
+ Asn1Encodable baseObject = GetOptionalBaseObject(taggedObject);
+ if (baseObject != null)
+ return new PkiArchiveOptions(taggedObject.TagNo, baseObject);
}
+ return null;
}
- public PkiArchiveOptions(EncryptedKey encKey)
+ private static Asn1Encodable GetOptionalBaseObject(Asn1TaggedObject taggedObject)
{
- this.value = encKey;
+ if (taggedObject.HasContextTag())
+ {
+ switch (taggedObject.TagNo)
+ {
+ case encryptedPrivKey:
+ // CHOICE so explicit
+ return EncryptedKey.GetInstance(taggedObject, true);
+ case keyGenParameters:
+ return Asn1OctetString.GetInstance(taggedObject, false);
+ case archiveRemGenPrivKey:
+ return DerBoolean.GetInstance(taggedObject, false);
+ }
+ }
+ return null;
}
- public PkiArchiveOptions(Asn1OctetString keyGenParameters)
+ private readonly int m_tagNo;
+ private readonly Asn1Encodable m_obj;
+
+ private PkiArchiveOptions(int tagNo, Asn1Encodable obj)
{
- this.value = keyGenParameters;
+ m_tagNo = tagNo;
+ m_obj = obj ?? throw new ArgumentNullException(nameof(obj));
}
- public PkiArchiveOptions(bool archiveRemGenPrivKey)
+ public PkiArchiveOptions(EncryptedKey encKey)
+ : this(encryptedPrivKey, encKey)
{
- this.value = DerBoolean.GetInstance(archiveRemGenPrivKey);
}
- public virtual int Type
+ public PkiArchiveOptions(Asn1OctetString keyGenParameters)
+ : this(PkiArchiveOptions.keyGenParameters, keyGenParameters)
{
- get
- {
- if (value is EncryptedKey)
- return encryptedPrivKey;
-
- if (value is Asn1OctetString)
- return keyGenParameters;
-
- return archiveRemGenPrivKey;
- }
}
- public virtual Asn1Encodable Value
+ public PkiArchiveOptions(bool archiveRemGenPrivKey)
+ : this(PkiArchiveOptions.archiveRemGenPrivKey, DerBoolean.GetInstance(archiveRemGenPrivKey))
{
- get { return value; }
}
+ public virtual int Type => m_tagNo;
+
+ public virtual Asn1Encodable Value => m_obj;
+
/**
* <pre>
* PkiArchiveOptions ::= CHOICE {
@@ -91,17 +107,8 @@ namespace Org.BouncyCastle.Asn1.Crmf
*/
public override Asn1Object ToAsn1Object()
{
- if (value is EncryptedKey)
- {
- return new DerTaggedObject(true, encryptedPrivKey, value); // choice
- }
-
- if (value is Asn1OctetString)
- {
- return new DerTaggedObject(false, keyGenParameters, value);
- }
-
- return new DerTaggedObject(false, archiveRemGenPrivKey, value);
+ // NOTE: Explicit tagging automatically applied for EncryptedKey (a CHOICE)
+ return new DerTaggedObject(false, m_tagNo, m_obj);
}
}
}
diff --git a/crypto/src/asn1/crmf/PKIPublicationInfo.cs b/crypto/src/asn1/crmf/PKIPublicationInfo.cs
index aac6d9911..5cc1df013 100644
--- a/crypto/src/asn1/crmf/PKIPublicationInfo.cs
+++ b/crypto/src/asn1/crmf/PKIPublicationInfo.cs
@@ -1,4 +1,6 @@
-using Org.BouncyCastle.Math;
+using System;
+
+using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Asn1.Crmf
{
@@ -22,13 +24,16 @@ namespace Org.BouncyCastle.Asn1.Crmf
public static PkiPublicationInfo GetInstance(object obj)
{
+ if (obj == null)
+ return null;
if (obj is PkiPublicationInfo pkiPublicationInfo)
return pkiPublicationInfo;
+ return new PkiPublicationInfo(Asn1Sequence.GetInstance(obj));
+ }
- if (obj != null)
- return new PkiPublicationInfo(Asn1Sequence.GetInstance(obj));
-
- return null;
+ public static PkiPublicationInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+ {
+ return new PkiPublicationInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
}
private readonly DerInteger m_action;
@@ -36,11 +41,17 @@ namespace Org.BouncyCastle.Asn1.Crmf
private PkiPublicationInfo(Asn1Sequence seq)
{
- m_action = DerInteger.GetInstance(seq[0]);
- if (seq.Count > 1)
- {
- m_pubInfos = Asn1Sequence.GetInstance(seq[1]);
- }
+ int count = seq.Count;
+ if (count < 1 || count > 2)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+ int pos = 0;
+
+ m_action = DerInteger.GetInstance(seq[pos++]);
+ m_pubInfos = Asn1Utilities.ReadOptional(seq, ref pos, Asn1Sequence.GetOptional);
+
+ if (pos != count)
+ throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
}
public PkiPublicationInfo(BigInteger action)
@@ -50,7 +61,7 @@ namespace Org.BouncyCastle.Asn1.Crmf
public PkiPublicationInfo(DerInteger action)
{
- m_action = action;
+ m_action = action ?? throw new ArgumentNullException(nameof(action));
}
/**
@@ -97,10 +108,9 @@ namespace Org.BouncyCastle.Asn1.Crmf
*/
public override Asn1Object ToAsn1Object()
{
- if (m_pubInfos == null)
- return new DerSequence(m_action);
-
- return new DerSequence(m_action, m_pubInfos);
+ return m_pubInfos == null
+ ? new DerSequence(m_action)
+ : new DerSequence(m_action, m_pubInfos);
}
}
}
diff --git a/crypto/src/asn1/crmf/PKMacValue.cs b/crypto/src/asn1/crmf/PKMacValue.cs
index 67e5ce6cc..02aeb0547 100644
--- a/crypto/src/asn1/crmf/PKMacValue.cs
+++ b/crypto/src/asn1/crmf/PKMacValue.cs
@@ -1,4 +1,6 @@
-using Org.BouncyCastle.Asn1.Cmp;
+using System;
+
+using Org.BouncyCastle.Asn1.Cmp;
using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.Crmf
@@ -28,6 +30,10 @@ namespace Org.BouncyCastle.Asn1.Crmf
private PKMacValue(Asn1Sequence seq)
{
+ int count = seq.Count;
+ if (count != 2)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
m_algID = AlgorithmIdentifier.GetInstance(seq[0]);
m_macValue = DerBitString.GetInstance(seq[1]);
}
diff --git a/crypto/src/asn1/crmf/PopoPrivKey.cs b/crypto/src/asn1/crmf/PopoPrivKey.cs
index 6e2d695da..13359d5bf 100644
--- a/crypto/src/asn1/crmf/PopoPrivKey.cs
+++ b/crypto/src/asn1/crmf/PopoPrivKey.cs
@@ -1,6 +1,7 @@
using System;
using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.Crmf
{
@@ -17,9 +18,15 @@ namespace Org.BouncyCastle.Asn1.Crmf
{
if (obj == null)
return null;
- if (obj is PopoPrivKey popoPrivKey)
- return popoPrivKey;
- return new PopoPrivKey(Asn1TaggedObject.GetInstance(obj, Asn1Tags.ContextSpecific));
+
+ if (obj is Asn1Encodable element)
+ {
+ var result = GetOptional(element);
+ if (result != null)
+ return result;
+ }
+
+ throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj));
}
public static PopoPrivKey GetInstance(Asn1TaggedObject tagged, bool isExplicit)
@@ -27,57 +34,65 @@ namespace Org.BouncyCastle.Asn1.Crmf
return Asn1Utilities.GetInstanceFromChoice(tagged, isExplicit, GetInstance);
}
- private readonly int tagNo;
- private readonly Asn1Encodable obj;
-
- private PopoPrivKey(Asn1TaggedObject obj)
+ public static PopoPrivKey GetOptional(Asn1Encodable element)
{
- this.tagNo = obj.TagNo;
-
- switch (tagNo)
+ if (element == null)
+ throw new ArgumentNullException(nameof(element));
+ if (element is PopoPrivKey popoPrivKey)
+ return popoPrivKey;
+ if (element is Asn1TaggedObject taggedObject)
{
- case thisMessage:
- this.obj = DerBitString.GetInstance(obj, false);
- break;
- case subsequentMessage:
- this.obj = SubsequentMessage.ValueOf(DerInteger.GetInstance(obj, false).IntValueExact);
- break;
- case dhMAC:
- this.obj = DerBitString.GetInstance(obj, false);
- break;
- case agreeMAC:
- this.obj = PKMacValue.GetInstance(obj, false);
- break;
- case encryptedKey:
- this.obj = EnvelopedData.GetInstance(obj, false);
- break;
- default:
- throw new ArgumentException("unknown tag in PopoPrivKey", "obj");
+ Asn1Encodable baseObject = GetOptionalBaseObject(taggedObject);
+ if (baseObject != null)
+ return new PopoPrivKey(taggedObject.TagNo, baseObject);
}
+ return null;
}
- public PopoPrivKey(PKMacValue pkMacValue)
+ private static Asn1Encodable GetOptionalBaseObject(Asn1TaggedObject taggedObject)
{
- this.tagNo = agreeMAC;
- this.obj = pkMacValue;
+ if (taggedObject.HasContextTag())
+ {
+ switch (taggedObject.TagNo)
+ {
+ case thisMessage:
+ case dhMAC:
+ return DerBitString.GetInstance(taggedObject, false);
+ case subsequentMessage:
+ return SubsequentMessage.ValueOf(DerInteger.GetInstance(taggedObject, false).IntValueExact);
+ case agreeMAC:
+ return PKMacValue.GetInstance(taggedObject, false);
+ case encryptedKey:
+ return EnvelopedData.GetInstance(taggedObject, false);
+
+ }
+ }
+ return null;
}
- public PopoPrivKey(SubsequentMessage msg)
+ private readonly int m_tagNo;
+ private readonly Asn1Encodable m_obj;
+
+ private PopoPrivKey(int tagNo, Asn1Encodable obj)
{
- this.tagNo = subsequentMessage;
- this.obj = msg;
+ m_tagNo = tagNo;
+ m_obj = obj ?? throw new ArgumentNullException(nameof(obj));
}
- public virtual int Type
+ public PopoPrivKey(PKMacValue pkMacValue)
+ : this(agreeMAC, pkMacValue)
{
- get { return tagNo; }
}
- public virtual Asn1Encodable Value
+ public PopoPrivKey(SubsequentMessage msg)
+ : this(subsequentMessage, msg)
{
- get { return obj; }
}
+ public virtual int Type => m_tagNo;
+
+ public virtual Asn1Encodable Value => m_obj;
+
/**
* <pre>
* PopoPrivKey ::= CHOICE {
@@ -91,9 +106,6 @@ namespace Org.BouncyCastle.Asn1.Crmf
* encryptedKey [4] EnvelopedData }
* </pre>
*/
- public override Asn1Object ToAsn1Object()
- {
- return new DerTaggedObject(false, tagNo, obj);
- }
+ public override Asn1Object ToAsn1Object() => new DerTaggedObject(false, m_tagNo, m_obj);
}
}
diff --git a/crypto/src/asn1/crmf/PopoSigningKey.cs b/crypto/src/asn1/crmf/PopoSigningKey.cs
index 2d30e1a67..00138ddb3 100644
--- a/crypto/src/asn1/crmf/PopoSigningKey.cs
+++ b/crypto/src/asn1/crmf/PopoSigningKey.cs
@@ -1,4 +1,6 @@
-using Org.BouncyCastle.Asn1.X509;
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.Crmf
{
@@ -25,17 +27,18 @@ namespace Org.BouncyCastle.Asn1.Crmf
private PopoSigningKey(Asn1Sequence seq)
{
- int index = 0;
+ int count = seq.Count;
+ if (count < 2 || count > 3)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+ int pos = 0;
- if (seq[index] is Asn1TaggedObject tagObj)
- {
- index++;
+ m_poposkInput = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, false, PopoSigningKeyInput.GetInstance);
+ m_algorithmIdentifier = AlgorithmIdentifier.GetInstance(seq[pos++]);
+ m_signature = DerBitString.GetInstance(seq[pos++]);
- m_poposkInput = PopoSigningKeyInput.GetInstance(
- Asn1Utilities.GetContextBaseUniversal(tagObj, 0, false, Asn1Tags.Sequence));
- }
- m_algorithmIdentifier = AlgorithmIdentifier.GetInstance(seq[index++]);
- m_signature = DerBitString.GetInstance(seq[index]);
+ if (pos != count)
+ throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
}
/**
@@ -49,8 +52,8 @@ namespace Org.BouncyCastle.Asn1.Crmf
public PopoSigningKey(PopoSigningKeyInput poposkIn, AlgorithmIdentifier aid, DerBitString signature)
{
m_poposkInput = poposkIn;
- m_algorithmIdentifier = aid;
- m_signature = signature;
+ m_algorithmIdentifier = aid ?? throw new ArgumentNullException(nameof(aid));
+ m_signature = signature ?? throw new ArgumentNullException(nameof(signature));
}
public virtual PopoSigningKeyInput PoposkInput => m_poposkInput;
diff --git a/crypto/src/asn1/crmf/PopoSigningKeyInput.cs b/crypto/src/asn1/crmf/PopoSigningKeyInput.cs
index 865ed669d..c62159051 100644
--- a/crypto/src/asn1/crmf/PopoSigningKeyInput.cs
+++ b/crypto/src/asn1/crmf/PopoSigningKeyInput.cs
@@ -1,4 +1,6 @@
-using Org.BouncyCastle.Asn1.X509;
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Asn1.Crmf
{
@@ -25,6 +27,10 @@ namespace Org.BouncyCastle.Asn1.Crmf
private PopoSigningKeyInput(Asn1Sequence seq)
{
+ int count = seq.Count;
+ if (count != 2)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
Asn1Encodable authInfo = (Asn1Encodable)seq[0];
if (authInfo is Asn1TaggedObject tagObj)
@@ -42,15 +48,15 @@ namespace Org.BouncyCastle.Asn1.Crmf
/** Creates a new PopoSigningKeyInput with sender name as authInfo. */
public PopoSigningKeyInput(GeneralName sender, SubjectPublicKeyInfo spki)
{
- m_sender = sender;
- m_publicKey = spki;
+ m_sender = sender ?? throw new ArgumentNullException(nameof(sender));
+ m_publicKey = spki ?? throw new ArgumentNullException(nameof(spki));
}
/** Creates a new PopoSigningKeyInput using password-based MAC. */
public PopoSigningKeyInput(PKMacValue pkmac, SubjectPublicKeyInfo spki)
{
- m_publicKeyMac = pkmac;
- m_publicKey = spki;
+ m_publicKeyMac = pkmac ?? throw new ArgumentNullException(nameof(pkmac));
+ m_publicKey = spki ?? throw new ArgumentNullException(nameof(spki));
}
/** Returns the sender field, or null if authInfo is publicKeyMac */
@@ -83,7 +89,7 @@ namespace Org.BouncyCastle.Asn1.Crmf
if (m_sender != null)
{
- v.Add(new DerTaggedObject(false, 0, m_sender));
+ v.Add(new DerTaggedObject(true, 0, m_sender));
}
else
{
diff --git a/crypto/src/asn1/crmf/ProofOfPossession.cs b/crypto/src/asn1/crmf/ProofOfPossession.cs
index 6ef62efda..0e6a64dac 100644
--- a/crypto/src/asn1/crmf/ProofOfPossession.cs
+++ b/crypto/src/asn1/crmf/ProofOfPossession.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Tls;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.Crmf
@@ -12,53 +13,79 @@ namespace Org.BouncyCastle.Asn1.Crmf
public const int TYPE_KEY_ENCIPHERMENT = 2;
public const int TYPE_KEY_AGREEMENT = 3;
- private readonly int tagNo;
- private readonly Asn1Encodable obj;
-
- private ProofOfPossession(Asn1TaggedObject tagged)
+ public static ProofOfPossession GetInstance(object obj)
{
- tagNo = tagged.TagNo;
- switch (tagNo)
+ if (obj == null)
+ return null;
+
+ if (obj is Asn1Encodable element)
{
- case 0:
- obj = DerNull.Instance;
- break;
- case 1:
- obj = PopoSigningKey.GetInstance(tagged, false);
- break;
- case 2:
- case 3:
- // CHOICE so explicit
- obj = PopoPrivKey.GetInstance(tagged, true);
- break;
- default:
- throw new ArgumentException("unknown tag: " + tagNo, "tagged");
+ var result = GetOptional(element);
+ if (result != null)
+ return result;
}
+
+ throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj));
}
- public static ProofOfPossession GetInstance(object obj)
+ public static ProofOfPossession GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
- if (obj is ProofOfPossession proofOfPossession)
+ return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance);
+ }
+
+ public static ProofOfPossession GetOptional(Asn1Encodable element)
+ {
+ if (element == null)
+ throw new ArgumentNullException(nameof(element));
+ if (element is ProofOfPossession proofOfPossession)
return proofOfPossession;
+ if (element is Asn1TaggedObject taggedObject)
+ {
+ Asn1Encodable baseObject = GetOptionalBaseObject(taggedObject);
+ if (baseObject != null)
+ return new ProofOfPossession(taggedObject.TagNo, baseObject);
+ }
+ return null;
+ }
- if (obj is Asn1TaggedObject taggedObject)
- return new ProofOfPossession(taggedObject);
+ private static Asn1Encodable GetOptionalBaseObject(Asn1TaggedObject taggedObject)
+ {
+ if (taggedObject.HasContextTag())
+ {
+ switch (taggedObject.TagNo)
+ {
+ case 0:
+ return DerNull.GetInstance(taggedObject, false);
+ case 1:
+ return PopoSigningKey.GetInstance(taggedObject, false);
+ case 2:
+ case 3:
+ // CHOICE so explicit
+ return PopoPrivKey.GetInstance(taggedObject, true);
+ }
+ }
+ return null;
+ }
+
+ private readonly int m_tagNo;
+ private readonly Asn1Encodable m_obj;
- throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj");
+ private ProofOfPossession(int tagNo, Asn1Encodable obj)
+ {
+ m_tagNo = tagNo;
+ m_obj = obj ?? throw new ArgumentNullException(nameof(obj));
}
/** Creates a ProofOfPossession with type raVerified. */
public ProofOfPossession()
+ : this(TYPE_RA_VERIFIED, DerNull.Instance)
{
- tagNo = TYPE_RA_VERIFIED;
- obj = DerNull.Instance;
}
/** Creates a ProofOfPossession for a signing key. */
public ProofOfPossession(PopoSigningKey Poposk)
+ : this(TYPE_SIGNING_KEY, Poposk)
{
- tagNo = TYPE_SIGNING_KEY;
- obj = Poposk;
}
/**
@@ -66,20 +93,13 @@ namespace Org.BouncyCastle.Asn1.Crmf
* @param type one of TYPE_KEY_ENCIPHERMENT or TYPE_KEY_AGREEMENT
*/
public ProofOfPossession(int type, PopoPrivKey privkey)
+ : this(type, (Asn1Encodable)privkey)
{
- tagNo = type;
- obj = privkey;
}
- public virtual int Type
- {
- get { return tagNo; }
- }
+ public virtual int Type => m_tagNo;
- public virtual Asn1Encodable Object
- {
- get { return obj; }
- }
+ public virtual Asn1Encodable Object => m_obj;
/**
* <pre>
@@ -95,7 +115,8 @@ namespace Org.BouncyCastle.Asn1.Crmf
*/
public override Asn1Object ToAsn1Object()
{
- return new DerTaggedObject(false, tagNo, obj);
+ // NOTE: Explicit tagging automatically applied for PopoPrivKey (a CHOICE)
+ return new DerTaggedObject(false, m_tagNo, m_obj);
}
}
}
diff --git a/crypto/src/asn1/crmf/SinglePubInfo.cs b/crypto/src/asn1/crmf/SinglePubInfo.cs
index 5205ce366..7d5d742fd 100644
--- a/crypto/src/asn1/crmf/SinglePubInfo.cs
+++ b/crypto/src/asn1/crmf/SinglePubInfo.cs
@@ -1,42 +1,50 @@
using System;
using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.Crmf
{
public class SinglePubInfo
: Asn1Encodable
{
- private readonly DerInteger pubMethod;
- private readonly GeneralName pubLocation;
-
- private SinglePubInfo(Asn1Sequence seq)
+ public static SinglePubInfo GetInstance(object obj)
{
- pubMethod = DerInteger.GetInstance(seq[0]);
+ if (obj == null)
+ return null;
+ if (obj is SinglePubInfo singlePubInfo)
+ return singlePubInfo;
+ return new SinglePubInfo(Asn1Sequence.GetInstance(obj));
+ }
- if (seq.Count == 2)
- {
- pubLocation = GeneralName.GetInstance(seq[1]);
- }
+ public static SinglePubInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+ {
+ return new SinglePubInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
}
- public static SinglePubInfo GetInstance(object obj)
+ private readonly DerInteger m_pubMethod;
+ private readonly GeneralName m_pubLocation;
+
+ private SinglePubInfo(Asn1Sequence seq)
{
- if (obj is SinglePubInfo)
- return (SinglePubInfo)obj;
+ int count = seq.Count;
+ if (count < 1 || count > 2)
+ throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
- if (obj is Asn1Sequence)
- return new SinglePubInfo((Asn1Sequence)obj);
+ int pos = 0;
- throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj");
- }
+ m_pubMethod = DerInteger.GetInstance(seq[pos++]);
- public virtual GeneralName PubLocation
- {
- get { return pubLocation; }
+ if (pos < count)
+ {
+ m_pubLocation = GeneralName.GetInstance(seq[pos++]);
+ }
+
+ if (pos != count)
+ throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
}
+ public virtual GeneralName PubLocation => m_pubLocation;
+
/**
* <pre>
* SinglePubInfo ::= SEQUENCE {
@@ -51,9 +59,9 @@ namespace Org.BouncyCastle.Asn1.Crmf
*/
public override Asn1Object ToAsn1Object()
{
- Asn1EncodableVector v = new Asn1EncodableVector(pubMethod);
- v.AddOptional(pubLocation);
- return new DerSequence(v);
+ return m_pubLocation == null
+ ? new DerSequence(m_pubMethod)
+ : new DerSequence(m_pubMethod, m_pubLocation);
}
}
}
|