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); } } }