001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.crypto.asn1.pkcs;
019
020 import java.io.ByteArrayInputStream;
021 import java.io.IOException;
022 import java.math.BigInteger;
023 import java.util.Enumeration;
024
025 import org.apache.geronimo.crypto.asn1.ASN1Encodable;
026 import org.apache.geronimo.crypto.asn1.ASN1EncodableVector;
027 import org.apache.geronimo.crypto.asn1.ASN1InputStream;
028 import org.apache.geronimo.crypto.asn1.ASN1OctetString;
029 import org.apache.geronimo.crypto.asn1.ASN1Sequence;
030 import org.apache.geronimo.crypto.asn1.ASN1Set;
031 import org.apache.geronimo.crypto.asn1.ASN1TaggedObject;
032 import org.apache.geronimo.crypto.asn1.DERInteger;
033 import org.apache.geronimo.crypto.asn1.DERObject;
034 import org.apache.geronimo.crypto.asn1.DEROctetString;
035 import org.apache.geronimo.crypto.asn1.DERSequence;
036 import org.apache.geronimo.crypto.asn1.DERTaggedObject;
037 import org.apache.geronimo.crypto.asn1.x509.AlgorithmIdentifier;
038
039 public class PrivateKeyInfo
040 extends ASN1Encodable
041 {
042 private DERObject privKey;
043 private AlgorithmIdentifier algId;
044 private ASN1Set attributes;
045
046 public static PrivateKeyInfo getInstance(
047 ASN1TaggedObject obj,
048 boolean explicit)
049 {
050 return getInstance(ASN1Sequence.getInstance(obj, explicit));
051 }
052
053 public static PrivateKeyInfo getInstance(
054 Object obj)
055 {
056 if (obj instanceof PrivateKeyInfo)
057 {
058 return (PrivateKeyInfo)obj;
059 }
060 else if (obj instanceof ASN1Sequence)
061 {
062 return new PrivateKeyInfo((ASN1Sequence)obj);
063 }
064
065 throw new IllegalArgumentException("unknown object in factory");
066 }
067
068 public PrivateKeyInfo(
069 AlgorithmIdentifier algId,
070 DERObject privateKey)
071 {
072 this.privKey = privateKey;
073 this.algId = algId;
074 }
075
076 public PrivateKeyInfo(
077 ASN1Sequence seq)
078 {
079 Enumeration e = seq.getObjects();
080
081 BigInteger version = ((DERInteger)e.nextElement()).getValue();
082 if (version.intValue() != 0)
083 {
084 throw new IllegalArgumentException("wrong version for private key info");
085 }
086
087 algId = new AlgorithmIdentifier((ASN1Sequence)e.nextElement());
088
089 try
090 {
091 ByteArrayInputStream bIn = new ByteArrayInputStream(((ASN1OctetString)e.nextElement()).getOctets());
092 ASN1InputStream aIn = new ASN1InputStream(bIn);
093
094 privKey = aIn.readObject();
095 }
096 catch (IOException ex)
097 {
098 throw new IllegalArgumentException("Error recoverying private key from sequence", ex);
099 }
100
101 if (e.hasMoreElements())
102 {
103 attributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false);
104 }
105 }
106
107 public AlgorithmIdentifier getAlgorithmId()
108 {
109 return algId;
110 }
111
112 public DERObject getPrivateKey()
113 {
114 return privKey;
115 }
116
117 public ASN1Set getAttributes()
118 {
119 return attributes;
120 }
121
122 /**
123 * write out an RSA private key with it's asscociated information
124 * as described in PKCS8.
125 * <pre>
126 * PrivateKeyInfo ::= SEQUENCE {
127 * version Version,
128 * privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
129 * privateKey PrivateKey,
130 * attributes [0] IMPLICIT Attributes OPTIONAL
131 * }
132 * Version ::= INTEGER {v1(0)} (v1,...)
133 *
134 * PrivateKey ::= OCTET STRING
135 *
136 * Attributes ::= SET OF Attribute
137 * </pre>
138 */
139 public DERObject toASN1Object()
140 {
141 ASN1EncodableVector v = new ASN1EncodableVector();
142
143 v.add(new DERInteger(0));
144 v.add(algId);
145 v.add(new DEROctetString(privKey));
146
147 if (attributes != null)
148 {
149 v.add(new DERTaggedObject(false, 0, attributes));
150 }
151
152 return new DERSequence(v);
153 }
154 }