diff options
Diffstat (limited to 'crypto/src/crmf/CertificateRequestMessage.cs')
-rw-r--r-- | crypto/src/crmf/CertificateRequestMessage.cs | 174 |
1 files changed, 103 insertions, 71 deletions
diff --git a/crypto/src/crmf/CertificateRequestMessage.cs b/crypto/src/crmf/CertificateRequestMessage.cs index d71e85e1f..8b8feb3f4 100644 --- a/crypto/src/crmf/CertificateRequestMessage.cs +++ b/crypto/src/crmf/CertificateRequestMessage.cs @@ -9,70 +9,61 @@ namespace Org.BouncyCastle.Crmf { public class CertificateRequestMessage { - public static readonly int popRaVerified = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_RA_VERIFIED; - public static readonly int popSigningKey = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_SIGNING_KEY; - public static readonly int popKeyEncipherment = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_KEY_ENCIPHERMENT; - public static readonly int popKeyAgreement = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_KEY_AGREEMENT; + public static readonly int popRaVerified = Asn1.Crmf.ProofOfPossession.TYPE_RA_VERIFIED; + public static readonly int popSigningKey = Asn1.Crmf.ProofOfPossession.TYPE_SIGNING_KEY; + public static readonly int popKeyEncipherment = Asn1.Crmf.ProofOfPossession.TYPE_KEY_ENCIPHERMENT; + public static readonly int popKeyAgreement = Asn1.Crmf.ProofOfPossession.TYPE_KEY_AGREEMENT; - private readonly CertReqMsg certReqMsg; - private readonly Controls controls; + private readonly CertReqMsg m_certReqMsg; + private readonly Controls m_controls; - private static CertReqMsg ParseBytes(byte[] encoding) - { - return CertReqMsg.GetInstance(encoding); - } + private static CertReqMsg ParseBytes(byte[] encoding) => CertReqMsg.GetInstance(encoding); /// <summary> /// Create a CertificateRequestMessage from the passed in bytes. /// </summary> /// <param name="encoded">BER/DER encoding of the CertReqMsg structure.</param> public CertificateRequestMessage(byte[] encoded) - : this(CertReqMsg.GetInstance(encoded)) + : this(ParseBytes(encoded)) { } public CertificateRequestMessage(CertReqMsg certReqMsg) { - this.certReqMsg = certReqMsg; - this.controls = certReqMsg.CertReq.Controls; + m_certReqMsg = certReqMsg; + m_controls = certReqMsg.CertReq.Controls; } /// <summary> /// Return the underlying ASN.1 object defining this CertificateRequestMessage object. /// </summary> /// <returns>A CertReqMsg</returns> - public CertReqMsg ToAsn1Structure() - { - return certReqMsg; - } + public CertReqMsg ToAsn1Structure() => m_certReqMsg; + + /// <summary> + /// Return the certificate request ID for this message. + /// </summary> + /// <returns>the certificate request ID.</returns> + public DerInteger GetCertReqID() => m_certReqMsg.CertReq.CertReqID; /// <summary> /// Return the certificate template contained in this message. /// </summary> /// <returns>a CertTemplate structure.</returns> - public CertTemplate GetCertTemplate() - { - return this.certReqMsg.CertReq.CertTemplate; - } + public CertTemplate GetCertTemplate() => m_certReqMsg.CertReq.CertTemplate; /// <summary> /// Return whether or not this request has control values associated with it. /// </summary> /// <returns>true if there are control values present, false otherwise.</returns> - public bool HasControls - { - get { return controls != null; } - } + public bool HasControls => m_controls != null; /// <summary> /// Return whether or not this request has a specific type of control value. /// </summary> /// <param name="objectIdentifier">the type OID for the control value we are checking for.</param> /// <returns>true if a control value of type is present, false otherwise.</returns> - public bool HasControl(DerObjectIdentifier objectIdentifier) - { - return FindControl(objectIdentifier) != null; - } + public bool HasControl(DerObjectIdentifier objectIdentifier) => FindControl(objectIdentifier) != null; /// <summary> /// Return a control value of the specified type. @@ -84,32 +75,26 @@ namespace Org.BouncyCastle.Crmf AttributeTypeAndValue found = FindControl(type); if (found != null) { - if (found.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_pkiArchiveOptions)) - { + var oid = found.Type; + + if (CrmfObjectIdentifiers.id_regCtrl_pkiArchiveOptions.Equals(oid)) return new PkiArchiveControl(PkiArchiveOptions.GetInstance(found.Value)); - } - if (found.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_regToken)) - { + if (CrmfObjectIdentifiers.id_regCtrl_regToken.Equals(oid)) return new RegTokenControl(DerUtf8String.GetInstance(found.Value)); - } - if (found.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_authenticator)) - { + if (CrmfObjectIdentifiers.id_regCtrl_authenticator.Equals(oid)) return new AuthenticatorControl(DerUtf8String.GetInstance(found.Value)); - } } return null; } public AttributeTypeAndValue FindControl(DerObjectIdentifier type) { - if (controls == null) - { + if (m_controls == null) return null; - } - AttributeTypeAndValue[] tAndV = controls.ToAttributeTypeAndValueArray(); + AttributeTypeAndValue[] tAndV = m_controls.ToAttributeTypeAndValueArray(); AttributeTypeAndValue found = null; for (int i = 0; i < tAndV.Length; i++) @@ -128,19 +113,13 @@ namespace Org.BouncyCastle.Crmf /// Return whether or not this request message has a proof-of-possession field in it. /// </summary> /// <returns>true if proof-of-possession is present, false otherwise.</returns> - public bool HasProofOfPossession - { - get { return certReqMsg.Pop != null; } - } + public bool HasProofOfPossession => m_certReqMsg.Pop != null; /// <summary> /// Return the type of the proof-of-possession this request message provides. /// </summary> /// <returns>one of: popRaVerified, popSigningKey, popKeyEncipherment, popKeyAgreement</returns> - public int ProofOfPossession - { - get { return certReqMsg.Pop.Type; } - } + public int ProofOfPossession => m_certReqMsg.Pop.Type; /// <summary> /// Return whether or not the proof-of-possession (POP) is of the type popSigningKey and @@ -151,16 +130,14 @@ namespace Org.BouncyCastle.Crmf { get { - ProofOfPossession pop = certReqMsg.Pop; + ProofOfPossession pop = m_certReqMsg.Pop; - if (pop.Type == popSigningKey) - { - PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object); + if (pop.Type != popSigningKey) + return false; - return popoSign.PoposkInput.PublicKeyMac != null; - } + PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object); - return false; + return popoSign.PoposkInput.PublicKeyMac != null; } } @@ -173,19 +150,77 @@ namespace Org.BouncyCastle.Crmf /// <exception cref="InvalidOperationException">if POP not appropriate.</exception> public bool IsValidSigningKeyPop(IVerifierFactoryProvider verifierProvider) { - ProofOfPossession pop = certReqMsg.Pop; - if (pop.Type == popSigningKey) - { - PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object); - if (popoSign.PoposkInput != null && popoSign.PoposkInput.PublicKeyMac != null) - throw new InvalidOperationException("verification requires password check"); + ProofOfPossession pop = m_certReqMsg.Pop; + if (pop.Type != popSigningKey) + throw new InvalidOperationException("not Signing Key type of proof of possession"); - return VerifySignature(verifierProvider, popoSign); - } + PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object); + if (popoSign.PoposkInput != null && popoSign.PoposkInput.PublicKeyMac != null) + throw new InvalidOperationException("verification requires password check"); - throw new InvalidOperationException("not Signing Key type of proof of possession"); + return VerifySignature(verifierProvider, popoSign); + } + + /// <summary> + /// Return whether or not a signing key proof-of-possession (POP), with an associated PKMAC, is valid. + /// </summary> + /// <param name="verifierProvider">a provider that can produce content verifiers for the signature contained in this POP.</param> + /// <param name="macBuilder">a suitable PKMacBuilder to create the MAC verifier.</param> + /// <param name="password">the password used to key the MAC calculation.</param> + /// <returns>true if the POP is valid, false otherwise.</returns> + /// <exception cref="InvalidOperationException">if there is a problem in verification or content verifier creation.</exception> + /// <exception cref="InvalidOperationException">if POP not appropriate.</exception> + public bool IsValidSigningKeyPop(IVerifierFactoryProvider verifierProvider, PKMacBuilder macBuilder, + char[] password) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return IsValidSigningKeyPop(verifierProvider, macBuilder, password.AsSpan()); +#else + ProofOfPossession pop = m_certReqMsg.Pop; + if (pop.Type != popSigningKey) + throw new InvalidOperationException("not Signing Key type of proof of possession"); + + PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object); + if (popoSign.PoposkInput == null || popoSign.PoposkInput.Sender != null) + throw new InvalidOperationException("no PKMAC present in proof of possession"); + + PKMacValue mac = popoSign.PoposkInput.PublicKeyMac; + PKMacValueVerifier macVerifier = new PKMacValueVerifier(macBuilder); + + return macVerifier.IsValid(mac, password, GetCertTemplate().PublicKey) + && VerifySignature(verifierProvider, popoSign); +#endif } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// <summary> + /// Return whether or not a signing key proof-of-possession (POP), with an associated PKMAC, is valid. + /// </summary> + /// <param name="verifierProvider">a provider that can produce content verifiers for the signature contained in this POP.</param> + /// <param name="macBuilder">a suitable PKMacBuilder to create the MAC verifier.</param> + /// <param name="password">the password used to key the MAC calculation.</param> + /// <returns>true if the POP is valid, false otherwise.</returns> + /// <exception cref="InvalidOperationException">if there is a problem in verification or content verifier creation.</exception> + /// <exception cref="InvalidOperationException">if POP not appropriate.</exception> + public bool IsValidSigningKeyPop(IVerifierFactoryProvider verifierProvider, PKMacBuilder macBuilder, + ReadOnlySpan<char> password) + { + ProofOfPossession pop = m_certReqMsg.Pop; + if (pop.Type != popSigningKey) + throw new InvalidOperationException("not Signing Key type of proof of possession"); + + PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object); + if (popoSign.PoposkInput == null || popoSign.PoposkInput.Sender != null) + throw new InvalidOperationException("no PKMAC present in proof of possession"); + + PKMacValue mac = popoSign.PoposkInput.PublicKeyMac; + PKMacValueVerifier macVerifier = new PKMacValueVerifier(macBuilder); + + return macVerifier.IsValid(mac, password, GetCertTemplate().PublicKey) + && VerifySignature(verifierProvider, popoSign); + } +#endif + private bool VerifySignature(IVerifierFactoryProvider verifierFactoryProvider, PopoSigningKey signKey) { var verifierFactory = verifierFactoryProvider.CreateVerifierFactory(signKey.AlgorithmIdentifier); @@ -193,7 +228,7 @@ namespace Org.BouncyCastle.Crmf Asn1Encodable asn1Encodable = signKey.PoposkInput; if (asn1Encodable == null) { - asn1Encodable = certReqMsg.CertReq; + asn1Encodable = m_certReqMsg.CertReq; } return X509.X509Utilities.VerifySignature(verifierFactory, asn1Encodable, signKey.Signature); @@ -203,9 +238,6 @@ namespace Org.BouncyCastle.Crmf /// Return the ASN.1 encoding of the certReqMsg we wrap. /// </summary> /// <returns>a byte array containing the binary encoding of the certReqMsg.</returns> - public byte[] GetEncoded() - { - return certReqMsg.GetEncoded(); - } + public byte[] GetEncoded() => m_certReqMsg.GetEncoded(); } } |