using System;
using System.Collections;
using System.Globalization;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Pkcs
{
///
/// A class for creating and verifying Pkcs10 Certification requests (this is an extension on ).
/// The requests are made using delay signing. This is useful for situations where
/// the private key is in another environment and not directly accessible (e.g. HSM)
/// So the first step creates the request, then the signing is done outside this
/// object and the signature is then used to complete the request.
///
///
/// CertificationRequest ::= Sequence {
/// certificationRequestInfo CertificationRequestInfo,
/// signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
/// signature BIT STRING
/// }
///
/// CertificationRequestInfo ::= Sequence {
/// version Integer { v1(0) } (v1,...),
/// subject Name,
/// subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
/// attributes [0] Attributes{{ CRIAttributes }}
/// }
///
/// Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }}
///
/// Attr { ATTRIBUTE:IOSet } ::= Sequence {
/// type ATTRIBUTE.&id({IOSet}),
/// values Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
/// }
///
/// see
public class Pkcs10CertificationRequestDelaySigned : Pkcs10CertificationRequest
{
protected Pkcs10CertificationRequestDelaySigned()
: base()
{
}
public Pkcs10CertificationRequestDelaySigned(
byte[] encoded)
: base(encoded)
{
}
public Pkcs10CertificationRequestDelaySigned(
Asn1Sequence seq)
: base(seq)
{
}
public Pkcs10CertificationRequestDelaySigned(
Stream input)
: base(input)
{
}
public Pkcs10CertificationRequestDelaySigned(
string signatureAlgorithm,
X509Name subject,
AsymmetricKeyParameter publicKey,
Asn1Set attributes,
AsymmetricKeyParameter signingKey)
: base(signatureAlgorithm, subject, publicKey, attributes, signingKey)
{
}
///
/// Instantiate a Pkcs10CertificationRequest object with the necessary credentials.
///
/// Name of Sig Alg.
/// X509Name of subject eg OU="My unit." O="My Organisatioin" C="au"
/// Public Key to be included in cert reqest.
/// ASN1Set of Attributes.
///
/// After the object is constructed use the and finally the
/// SignRequest methods to finalize the request.
///
public Pkcs10CertificationRequestDelaySigned(
string signatureAlgorithm,
X509Name subject,
AsymmetricKeyParameter publicKey,
Asn1Set attributes)
{
if (signatureAlgorithm == null)
throw new ArgumentNullException("signatureAlgorithm");
if (subject == null)
throw new ArgumentNullException("subject");
if (publicKey == null)
throw new ArgumentNullException("publicKey");
if (publicKey.IsPrivate)
throw new ArgumentException("expected public key", "publicKey");
// DerObjectIdentifier sigOid = SignerUtilities.GetObjectIdentifier(signatureAlgorithm);
string algorithmName = Platform.ToUpperInvariant(signatureAlgorithm);
DerObjectIdentifier sigOid = (DerObjectIdentifier) algorithms[algorithmName];
if (sigOid == null)
{
try
{
sigOid = new DerObjectIdentifier(algorithmName);
}
catch (Exception e)
{
throw new ArgumentException("Unknown signature type requested", e);
}
}
if (noParams.Contains(sigOid))
{
this.sigAlgId = new AlgorithmIdentifier(sigOid);
}
else if (exParams.Contains(algorithmName))
{
this.sigAlgId = new AlgorithmIdentifier(sigOid, (Asn1Encodable) exParams[algorithmName]);
}
else
{
this.sigAlgId = new AlgorithmIdentifier(sigOid, DerNull.Instance);
}
SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
this.reqInfo = new CertificationRequestInfo(subject, pubInfo, attributes);
}
public byte[] GetDataToSign()
{
return reqInfo.GetDerEncoded();
}
public void SignRequest(byte[] signedData)
{
//build the signature from the signed data
sigBits = new DerBitString(signedData);
}
public void SignRequest(DerBitString signedData)
{
//build the signature from the signed data
sigBits = signedData;
}
}
}