1package org.bouncycastle.asn1.pkcs; 2 3import org.bouncycastle.asn1.ASN1Encodable; 4import org.bouncycastle.asn1.ASN1EncodableVector; 5import org.bouncycastle.asn1.ASN1InputStream; 6import org.bouncycastle.asn1.ASN1OctetString; 7import org.bouncycastle.asn1.ASN1Sequence; 8import org.bouncycastle.asn1.ASN1Set; 9import org.bouncycastle.asn1.ASN1TaggedObject; 10import org.bouncycastle.asn1.DERInteger; 11import org.bouncycastle.asn1.DERObject; 12import org.bouncycastle.asn1.DEROctetString; 13import org.bouncycastle.asn1.DERSequence; 14import org.bouncycastle.asn1.DERTaggedObject; 15import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 16 17import java.io.IOException; 18import java.math.BigInteger; 19import java.util.Enumeration; 20 21public class PrivateKeyInfo 22 extends ASN1Encodable 23{ 24 private DERObject privKey; 25 private AlgorithmIdentifier algId; 26 private ASN1Set attributes; 27 28 public static PrivateKeyInfo getInstance( 29 ASN1TaggedObject obj, 30 boolean explicit) 31 { 32 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 33 } 34 35 public static PrivateKeyInfo getInstance( 36 Object obj) 37 { 38 if (obj instanceof PrivateKeyInfo) 39 { 40 return (PrivateKeyInfo)obj; 41 } 42 else if (obj instanceof ASN1Sequence) 43 { 44 return new PrivateKeyInfo((ASN1Sequence)obj); 45 } 46 47 throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); 48 } 49 50 public PrivateKeyInfo( 51 AlgorithmIdentifier algId, 52 DERObject privateKey) 53 { 54 this(algId, privateKey, null); 55 } 56 57 public PrivateKeyInfo( 58 AlgorithmIdentifier algId, 59 DERObject privateKey, 60 ASN1Set attributes) 61 { 62 this.privKey = privateKey; 63 this.algId = algId; 64 this.attributes = attributes; 65 } 66 67 public PrivateKeyInfo( 68 ASN1Sequence seq) 69 { 70 Enumeration e = seq.getObjects(); 71 72 BigInteger version = ((DERInteger)e.nextElement()).getValue(); 73 if (version.intValue() != 0) 74 { 75 throw new IllegalArgumentException("wrong version for private key info"); 76 } 77 78 algId = new AlgorithmIdentifier((ASN1Sequence)e.nextElement()); 79 80 try 81 { 82 ASN1InputStream aIn = new ASN1InputStream(((ASN1OctetString)e.nextElement()).getOctets()); 83 84 privKey = aIn.readObject(); 85 } 86 catch (IOException ex) 87 { 88 throw new IllegalArgumentException("Error recoverying private key from sequence"); 89 } 90 91 if (e.hasMoreElements()) 92 { 93 attributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false); 94 } 95 } 96 97 public AlgorithmIdentifier getAlgorithmId() 98 { 99 return algId; 100 } 101 102 public DERObject getPrivateKey() 103 { 104 return privKey; 105 } 106 107 public ASN1Set getAttributes() 108 { 109 return attributes; 110 } 111 112 /** 113 * write out an RSA private key with its associated information 114 * as described in PKCS8. 115 * <pre> 116 * PrivateKeyInfo ::= SEQUENCE { 117 * version Version, 118 * privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}}, 119 * privateKey PrivateKey, 120 * attributes [0] IMPLICIT Attributes OPTIONAL 121 * } 122 * Version ::= INTEGER {v1(0)} (v1,...) 123 * 124 * PrivateKey ::= OCTET STRING 125 * 126 * Attributes ::= SET OF Attribute 127 * </pre> 128 */ 129 public DERObject toASN1Object() 130 { 131 ASN1EncodableVector v = new ASN1EncodableVector(); 132 133 v.add(new DERInteger(0)); 134 v.add(algId); 135 v.add(new DEROctetString(privKey)); 136 137 if (attributes != null) 138 { 139 v.add(new DERTaggedObject(false, 0, attributes)); 140 } 141 142 return new DERSequence(v); 143 } 144} 145