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