139 lines
3.9 KiB
C#
139 lines
3.9 KiB
C#
using System;
|
|
using System.Collections;
|
|
using Org.BouncyCastle.Asn1.X509;
|
|
using Org.BouncyCastle.Math;
|
|
using Org.BouncyCastle.Utilities.Collections;
|
|
|
|
namespace Org.BouncyCastle.Asn1.Pkcs;
|
|
|
|
public class PrivateKeyInfo : Asn1Encodable
|
|
{
|
|
private readonly DerInteger version;
|
|
|
|
private readonly AlgorithmIdentifier privateKeyAlgorithm;
|
|
|
|
private readonly Asn1OctetString privateKey;
|
|
|
|
private readonly Asn1Set attributes;
|
|
|
|
private readonly DerBitString publicKey;
|
|
|
|
public virtual Asn1Set Attributes => attributes;
|
|
|
|
public virtual bool HasPublicKey => publicKey != null;
|
|
|
|
public virtual AlgorithmIdentifier PrivateKeyAlgorithm => privateKeyAlgorithm;
|
|
|
|
public virtual DerBitString PublicKeyData => publicKey;
|
|
|
|
public static PrivateKeyInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
|
|
{
|
|
return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
|
|
}
|
|
|
|
public static PrivateKeyInfo GetInstance(object obj)
|
|
{
|
|
if (obj == null)
|
|
{
|
|
return null;
|
|
}
|
|
if (obj is PrivateKeyInfo)
|
|
{
|
|
return (PrivateKeyInfo)obj;
|
|
}
|
|
return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj));
|
|
}
|
|
|
|
private static int GetVersionValue(DerInteger version)
|
|
{
|
|
BigInteger value = version.Value;
|
|
if (value.CompareTo(BigInteger.Zero) < 0 || value.CompareTo(BigInteger.One) > 0)
|
|
{
|
|
throw new ArgumentException("invalid version for private key info", "version");
|
|
}
|
|
return value.IntValue;
|
|
}
|
|
|
|
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)
|
|
{
|
|
version = new DerInteger((publicKey != null) ? BigInteger.One : BigInteger.Zero);
|
|
this.privateKeyAlgorithm = privateKeyAlgorithm;
|
|
this.privateKey = new DerOctetString(privateKey);
|
|
this.attributes = attributes;
|
|
this.publicKey = ((publicKey == null) ? null : new DerBitString(publicKey));
|
|
}
|
|
|
|
private PrivateKeyInfo(Asn1Sequence seq)
|
|
{
|
|
IEnumerator enumerator = seq.GetEnumerator();
|
|
version = DerInteger.GetInstance(CollectionUtilities.RequireNext(enumerator));
|
|
int versionValue = GetVersionValue(version);
|
|
privateKeyAlgorithm = AlgorithmIdentifier.GetInstance(CollectionUtilities.RequireNext(enumerator));
|
|
privateKey = Asn1OctetString.GetInstance(CollectionUtilities.RequireNext(enumerator));
|
|
int num = -1;
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Asn1TaggedObject asn1TaggedObject = (Asn1TaggedObject)enumerator.Current;
|
|
int tagNo = asn1TaggedObject.TagNo;
|
|
if (tagNo <= num)
|
|
{
|
|
throw new ArgumentException("invalid optional field in private key info", "seq");
|
|
}
|
|
num = tagNo;
|
|
switch (tagNo)
|
|
{
|
|
case 0:
|
|
attributes = Asn1Set.GetInstance(asn1TaggedObject, explicitly: false);
|
|
break;
|
|
case 1:
|
|
if (versionValue < 1)
|
|
{
|
|
throw new ArgumentException("'publicKey' requires version v2(1) or later", "seq");
|
|
}
|
|
publicKey = DerBitString.GetInstance(asn1TaggedObject, isExplicit: false);
|
|
break;
|
|
default:
|
|
throw new ArgumentException("unknown optional field in private key info", "seq");
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual Asn1Object ParsePrivateKey()
|
|
{
|
|
return Asn1Object.FromByteArray(privateKey.GetOctets());
|
|
}
|
|
|
|
public virtual Asn1Object ParsePublicKey()
|
|
{
|
|
if (publicKey != null)
|
|
{
|
|
return Asn1Object.FromByteArray(publicKey.GetOctets());
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override Asn1Object ToAsn1Object()
|
|
{
|
|
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(version, privateKeyAlgorithm, privateKey);
|
|
if (attributes != null)
|
|
{
|
|
asn1EncodableVector.Add(new DerTaggedObject(explicitly: false, 0, attributes));
|
|
}
|
|
if (publicKey != null)
|
|
{
|
|
asn1EncodableVector.Add(new DerTaggedObject(explicitly: false, 1, publicKey));
|
|
}
|
|
return new DerSequence(asn1EncodableVector);
|
|
}
|
|
}
|