using System; using System.Collections; using System.IO; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; namespace Org.BouncyCastle.Asn1.Pkcs { public class PrivateKeyInfo : Asn1Encodable { private readonly Asn1Object privKey; private readonly AlgorithmIdentifier algID; private readonly Asn1Set attributes; public static PrivateKeyInfo GetInstance( object obj) { if (obj is PrivateKeyInfo) return (PrivateKeyInfo) obj; if (obj != null) return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj)); return null; } public PrivateKeyInfo( AlgorithmIdentifier algID, Asn1Object privateKey) : this(algID, privateKey, null) { } public PrivateKeyInfo( AlgorithmIdentifier algID, Asn1Object privateKey, Asn1Set attributes) { this.privKey = privateKey; this.algID = algID; this.attributes = attributes; } private PrivateKeyInfo( Asn1Sequence seq) { IEnumerator e = seq.GetEnumerator(); e.MoveNext(); BigInteger version = ((DerInteger) e.Current).Value; if (version.IntValue != 0) { throw new ArgumentException("wrong version for private key info: " + version.IntValue); } e.MoveNext(); algID = AlgorithmIdentifier.GetInstance(e.Current); try { e.MoveNext(); Asn1OctetString data = (Asn1OctetString) e.Current; privKey = Asn1Object.FromByteArray(data.GetOctets()); } catch (IOException) { throw new ArgumentException("Error recoverying private key from sequence"); } if (e.MoveNext()) { attributes = Asn1Set.GetInstance((Asn1TaggedObject) e.Current, false); } } public AlgorithmIdentifier AlgorithmID { get { return algID; } } public Asn1Object PrivateKey { get { return privKey; } } public Asn1Set Attributes { get { return attributes; } } /** * write out an RSA private key with its associated information * as described in Pkcs8. *
* PrivateKeyInfo ::= Sequence { * version Version, * privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}}, * privateKey PrivateKey, * attributes [0] IMPLICIT Attributes OPTIONAL * } * Version ::= Integer {v1(0)} (v1,...) * * PrivateKey ::= OCTET STRING * * Attributes ::= Set OF Attr **/ public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector( new DerInteger(0), algID, new DerOctetString(privKey)); if (attributes != null) { v.Add(new DerTaggedObject(false, 0, attributes)); } return new DerSequence(v); } } }