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