PrivateKeyInfo
using Org.BouncyCastle.Asn1.X509;
using System;
namespace Org.BouncyCastle.Asn1.Pkcs
{
public class PrivateKeyInfo : Asn1Encodable
{
private readonly DerInteger m_version;
private readonly AlgorithmIdentifier m_privateKeyAlgorithm;
private readonly Asn1OctetString m_privateKey;
private readonly Asn1Set m_attributes;
private readonly DerBitString m_publicKey;
public virtual DerInteger Version => m_version;
public virtual Asn1Set Attributes => m_attributes;
public virtual bool HasPublicKey => m_publicKey != null;
public virtual AlgorithmIdentifier PrivateKeyAlgorithm => m_privateKeyAlgorithm;
public virtual Asn1OctetString PrivateKey => m_privateKey;
[Obsolete("Use 'PrivateKey' instead")]
public virtual Asn1OctetString PrivateKeyData {
get {
return m_privateKey;
}
}
public virtual int PrivateKeyLength => m_privateKey.GetOctetsLength();
public virtual DerBitString PublicKey => m_publicKey;
[Obsolete("Use 'PublicKey' instead")]
public virtual DerBitString PublicKeyData {
get {
return m_publicKey;
}
}
public static PrivateKeyInfo Create(AlgorithmIdentifier privateKeyAlgorithm, Asn1OctetString privateKey, Asn1Set attributes, DerBitString publicKey)
{
return new PrivateKeyInfo(new DerInteger((publicKey != null) ? 1 : 0), privateKeyAlgorithm, privateKey, attributes, publicKey);
}
public static PrivateKeyInfo GetInstance(object obj)
{
if (obj == null)
return null;
PrivateKeyInfo privateKeyInfo = obj as PrivateKeyInfo;
if (privateKeyInfo != null)
return privateKeyInfo;
return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj));
}
public static PrivateKeyInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
{
return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj, explicitly));
}
public static PrivateKeyInfo GetOptional(Asn1Encodable element)
{
if (element == null)
throw new ArgumentNullException("element");
PrivateKeyInfo privateKeyInfo = element as PrivateKeyInfo;
if (privateKeyInfo != null)
return privateKeyInfo;
Asn1Sequence optional = Asn1Sequence.GetOptional(element);
if (optional != null)
return new PrivateKeyInfo(optional);
return null;
}
public static PrivateKeyInfo GetTagged(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
return new PrivateKeyInfo(Asn1Sequence.GetTagged(taggedObject, declaredExplicit));
}
private PrivateKeyInfo(Asn1Sequence seq)
{
int count = seq.Count;
int sequencePosition = 0;
if (count < 3 || count > 5)
throw new ArgumentException("Bad sequence size: " + count.ToString(), "seq");
m_version = DerInteger.GetInstance(seq[sequencePosition++]);
m_privateKeyAlgorithm = AlgorithmIdentifier.GetInstance(seq[sequencePosition++]);
m_privateKey = Asn1OctetString.GetInstance(seq[sequencePosition++]);
m_attributes = Asn1Utilities.ReadOptionalContextTagged(seq, ref sequencePosition, 0, false, Asn1Set.GetTagged);
m_publicKey = Asn1Utilities.ReadOptionalContextTagged(seq, ref sequencePosition, 1, false, DerBitString.GetTagged);
if (sequencePosition != count)
throw new ArgumentException("Unexpected elements in sequence", "seq");
int versionValue = GetVersionValue(m_version);
if (m_publicKey != null && versionValue < 1)
throw new ArgumentException("'publicKey' requires version v2(1) or later", "seq");
}
public PrivateKeyInfo(AlgorithmIdentifier privateKeyAlgorithm, Asn1Encodable privateKey)
: this(privateKeyAlgorithm, privateKey, null, null)
{
}
public PrivateKeyInfo(AlgorithmIdentifier privateKeyAlgorithm, Asn1Encodable privateKey, Asn1Set attributes)
: this(privateKeyAlgorithm, privateKey, attributes, null)
{
}
public PrivateKeyInfo(AlgorithmIdentifier privateKeyAlgorithm, Asn1Encodable privateKey, Asn1Set attributes, byte[] publicKey)
{
m_version = new DerInteger((publicKey != null) ? 1 : 0);
if (privateKeyAlgorithm == null)
throw new ArgumentNullException("privateKeyAlgorithm");
m_privateKeyAlgorithm = privateKeyAlgorithm;
m_privateKey = new DerOctetString(privateKey);
m_attributes = attributes;
m_publicKey = ((publicKey == null) ? null : new DerBitString(publicKey));
}
private PrivateKeyInfo(DerInteger version, AlgorithmIdentifier privateKeyAlgorithm, Asn1OctetString privateKey, Asn1Set attributes, DerBitString publicKey)
{
if (version == null)
throw new ArgumentNullException("version");
m_version = version;
if (privateKeyAlgorithm == null)
throw new ArgumentNullException("privateKeyAlgorithm");
m_privateKeyAlgorithm = privateKeyAlgorithm;
if (privateKey == null)
throw new ArgumentNullException("privateKey");
m_privateKey = privateKey;
m_attributes = attributes;
m_publicKey = publicKey;
}
public virtual Asn1Object ParsePrivateKey()
{
return Asn1Object.FromByteArray(m_privateKey.GetOctets());
}
public virtual Asn1Object ParsePublicKey()
{
if (m_publicKey != null)
return Asn1Object.FromMemoryStream(m_publicKey.GetOctetMemoryStream());
return null;
}
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(5);
asn1EncodableVector.Add(m_version, m_privateKeyAlgorithm, m_privateKey);
asn1EncodableVector.AddOptionalTagged(false, 0, m_attributes);
asn1EncodableVector.AddOptionalTagged(false, 1, m_publicKey);
return new DerSequence(asn1EncodableVector);
}
private static int GetVersionValue(DerInteger version)
{
int value;
if (version.TryGetIntPositiveValueExact(out value) && value >= 0 && value <= 1)
return value;
throw new ArgumentException("Invalid version for PrivateKeyInfo", "version");
}
}
}