160 lines
4.2 KiB
C#
160 lines
4.2 KiB
C#
using System;
|
|
using Org.BouncyCastle.Asn1;
|
|
using Org.BouncyCastle.Asn1.Crmf;
|
|
using Org.BouncyCastle.Crypto;
|
|
using Org.BouncyCastle.Crypto.Operators;
|
|
|
|
namespace Org.BouncyCastle.Crmf;
|
|
|
|
public class CertificateRequestMessage
|
|
{
|
|
public static readonly int popRaVerified = 0;
|
|
|
|
public static readonly int popSigningKey = 1;
|
|
|
|
public static readonly int popKeyEncipherment = 2;
|
|
|
|
public static readonly int popKeyAgreement = 3;
|
|
|
|
private readonly CertReqMsg certReqMsg;
|
|
|
|
private readonly Controls controls;
|
|
|
|
public bool HasControls => controls != null;
|
|
|
|
public bool HasProofOfPossession => certReqMsg.Popo != null;
|
|
|
|
public int ProofOfPossession => certReqMsg.Popo.Type;
|
|
|
|
public bool HasSigningKeyProofOfPossessionWithPkMac
|
|
{
|
|
get
|
|
{
|
|
ProofOfPossession popo = certReqMsg.Popo;
|
|
if (popo.Type == popSigningKey)
|
|
{
|
|
PopoSigningKey instance = PopoSigningKey.GetInstance(popo.Object);
|
|
return instance.PoposkInput.PublicKeyMac != null;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static CertReqMsg ParseBytes(byte[] encoding)
|
|
{
|
|
return CertReqMsg.GetInstance(encoding);
|
|
}
|
|
|
|
public CertificateRequestMessage(byte[] encoded)
|
|
: this(CertReqMsg.GetInstance(encoded))
|
|
{
|
|
}
|
|
|
|
public CertificateRequestMessage(CertReqMsg certReqMsg)
|
|
{
|
|
this.certReqMsg = certReqMsg;
|
|
controls = certReqMsg.CertReq.Controls;
|
|
}
|
|
|
|
public CertReqMsg ToAsn1Structure()
|
|
{
|
|
return certReqMsg;
|
|
}
|
|
|
|
public CertTemplate GetCertTemplate()
|
|
{
|
|
return certReqMsg.CertReq.CertTemplate;
|
|
}
|
|
|
|
public bool HasControl(DerObjectIdentifier objectIdentifier)
|
|
{
|
|
return FindControl(objectIdentifier) != null;
|
|
}
|
|
|
|
public IControl GetControl(DerObjectIdentifier type)
|
|
{
|
|
AttributeTypeAndValue attributeTypeAndValue = FindControl(type);
|
|
if (attributeTypeAndValue != null)
|
|
{
|
|
if (attributeTypeAndValue.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_pkiArchiveOptions))
|
|
{
|
|
return new PkiArchiveControl(PkiArchiveOptions.GetInstance(attributeTypeAndValue.Value));
|
|
}
|
|
if (attributeTypeAndValue.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_regToken))
|
|
{
|
|
return new RegTokenControl(DerUtf8String.GetInstance(attributeTypeAndValue.Value));
|
|
}
|
|
if (attributeTypeAndValue.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_authenticator))
|
|
{
|
|
return new AuthenticatorControl(DerUtf8String.GetInstance(attributeTypeAndValue.Value));
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public AttributeTypeAndValue FindControl(DerObjectIdentifier type)
|
|
{
|
|
if (controls == null)
|
|
{
|
|
return null;
|
|
}
|
|
AttributeTypeAndValue[] array = controls.ToAttributeTypeAndValueArray();
|
|
AttributeTypeAndValue result = null;
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (array[i].Type.Equals(type))
|
|
{
|
|
result = array[i];
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public bool IsValidSigningKeyPop(IVerifierFactoryProvider verifierProvider)
|
|
{
|
|
ProofOfPossession popo = certReqMsg.Popo;
|
|
if (popo.Type == popSigningKey)
|
|
{
|
|
PopoSigningKey instance = PopoSigningKey.GetInstance(popo.Object);
|
|
if (instance.PoposkInput != null && instance.PoposkInput.PublicKeyMac != null)
|
|
{
|
|
throw new InvalidOperationException("verification requires password check");
|
|
}
|
|
return verifySignature(verifierProvider, instance);
|
|
}
|
|
throw new InvalidOperationException("not Signing Key type of proof of possession");
|
|
}
|
|
|
|
private bool verifySignature(IVerifierFactoryProvider verifierFactoryProvider, PopoSigningKey signKey)
|
|
{
|
|
IStreamCalculator streamCalculator;
|
|
try
|
|
{
|
|
IVerifierFactory verifierFactory = verifierFactoryProvider.CreateVerifierFactory(signKey.AlgorithmIdentifier);
|
|
streamCalculator = verifierFactory.CreateCalculator();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new CrmfException("unable to create verifier: " + ex.Message, ex);
|
|
}
|
|
if (signKey.PoposkInput != null)
|
|
{
|
|
byte[] derEncoded = signKey.GetDerEncoded();
|
|
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
|
|
}
|
|
else
|
|
{
|
|
byte[] derEncoded2 = certReqMsg.CertReq.GetDerEncoded();
|
|
streamCalculator.Stream.Write(derEncoded2, 0, derEncoded2.Length);
|
|
}
|
|
DefaultVerifierResult defaultVerifierResult = (DefaultVerifierResult)streamCalculator.GetResult();
|
|
return defaultVerifierResult.IsVerified(signKey.Signature.GetBytes());
|
|
}
|
|
|
|
public byte[] GetEncoded()
|
|
{
|
|
return certReqMsg.GetEncoded();
|
|
}
|
|
}
|