001: package org.bouncycastle.asn1.pkcs;
002:
003: import org.bouncycastle.asn1.ASN1Encodable;
004: import org.bouncycastle.asn1.ASN1EncodableVector;
005: import org.bouncycastle.asn1.ASN1InputStream;
006: import org.bouncycastle.asn1.ASN1OctetString;
007: import org.bouncycastle.asn1.ASN1Sequence;
008: import org.bouncycastle.asn1.ASN1Set;
009: import org.bouncycastle.asn1.ASN1TaggedObject;
010: import org.bouncycastle.asn1.DERInteger;
011: import org.bouncycastle.asn1.DERObject;
012: import org.bouncycastle.asn1.DEROctetString;
013: import org.bouncycastle.asn1.DERSequence;
014: import org.bouncycastle.asn1.DERTaggedObject;
015: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
016:
017: import java.io.IOException;
018: import java.math.BigInteger;
019: import java.util.Enumeration;
020:
021: public class PrivateKeyInfo extends ASN1Encodable {
022: private DERObject privKey;
023: private AlgorithmIdentifier algId;
024: private ASN1Set attributes;
025:
026: public static PrivateKeyInfo getInstance(ASN1TaggedObject obj,
027: boolean explicit) {
028: return getInstance(ASN1Sequence.getInstance(obj, explicit));
029: }
030:
031: public static PrivateKeyInfo getInstance(Object obj) {
032: if (obj instanceof PrivateKeyInfo) {
033: return (PrivateKeyInfo) obj;
034: } else if (obj instanceof ASN1Sequence) {
035: return new PrivateKeyInfo((ASN1Sequence) obj);
036: }
037:
038: throw new IllegalArgumentException("unknown object in factory");
039: }
040:
041: public PrivateKeyInfo(AlgorithmIdentifier algId,
042: DERObject privateKey) {
043: this (algId, privateKey, null);
044: }
045:
046: public PrivateKeyInfo(AlgorithmIdentifier algId,
047: DERObject privateKey, ASN1Set attributes) {
048: this .privKey = privateKey;
049: this .algId = algId;
050: this .attributes = attributes;
051: }
052:
053: public PrivateKeyInfo(ASN1Sequence seq) {
054: Enumeration e = seq.getObjects();
055:
056: BigInteger version = ((DERInteger) e.nextElement()).getValue();
057: if (version.intValue() != 0) {
058: throw new IllegalArgumentException(
059: "wrong version for private key info");
060: }
061:
062: algId = new AlgorithmIdentifier((ASN1Sequence) e.nextElement());
063:
064: try {
065: ASN1InputStream aIn = new ASN1InputStream(
066: ((ASN1OctetString) e.nextElement()).getOctets());
067:
068: privKey = aIn.readObject();
069: } catch (IOException ex) {
070: throw new IllegalArgumentException(
071: "Error recoverying private key from sequence");
072: }
073:
074: if (e.hasMoreElements()) {
075: attributes = ASN1Set.getInstance((ASN1TaggedObject) e
076: .nextElement(), false);
077: }
078: }
079:
080: public AlgorithmIdentifier getAlgorithmId() {
081: return algId;
082: }
083:
084: public DERObject getPrivateKey() {
085: return privKey;
086: }
087:
088: public ASN1Set getAttributes() {
089: return attributes;
090: }
091:
092: /**
093: * write out an RSA private key with it's asscociated information
094: * as described in PKCS8.
095: * <pre>
096: * PrivateKeyInfo ::= SEQUENCE {
097: * version Version,
098: * privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
099: * privateKey PrivateKey,
100: * attributes [0] IMPLICIT Attributes OPTIONAL
101: * }
102: * Version ::= INTEGER {v1(0)} (v1,...)
103: *
104: * PrivateKey ::= OCTET STRING
105: *
106: * Attributes ::= SET OF Attribute
107: * </pre>
108: */
109: public DERObject toASN1Object() {
110: ASN1EncodableVector v = new ASN1EncodableVector();
111:
112: v.add(new DERInteger(0));
113: v.add(algId);
114: v.add(new DEROctetString(privKey));
115:
116: if (attributes != null) {
117: v.add(new DERTaggedObject(false, 0, attributes));
118: }
119:
120: return new DERSequence(v);
121: }
122: }
|