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.util.jce.provider;
019
020 import java.io.ByteArrayOutputStream;
021 import java.io.IOException;
022 import java.io.ObjectInputStream;
023 import java.io.ObjectOutputStream;
024 import java.math.BigInteger;
025 import java.util.Enumeration;
026 import java.util.Hashtable;
027 import java.util.Vector;
028
029 import javax.crypto.interfaces.DHPrivateKey;
030 import javax.crypto.spec.DHParameterSpec;
031 import javax.crypto.spec.DHPrivateKeySpec;
032
033 import org.apache.geronimo.util.asn1.ASN1Sequence;
034 import org.apache.geronimo.util.asn1.DEREncodable;
035 import org.apache.geronimo.util.asn1.DERInteger;
036 import org.apache.geronimo.util.asn1.DERObjectIdentifier;
037 import org.apache.geronimo.util.asn1.DEROutputStream;
038 import org.apache.geronimo.util.asn1.pkcs.DHParameter;
039 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers;
040 import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo;
041 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier;
042 import org.apache.geronimo.util.crypto.params.DHPrivateKeyParameters;
043 import org.apache.geronimo.util.jce.interfaces.PKCS12BagAttributeCarrier;
044
045 public class JCEDHPrivateKey
046 implements DHPrivateKey, PKCS12BagAttributeCarrier
047 {
048 BigInteger x;
049
050 DHParameterSpec dhSpec;
051
052 private Hashtable pkcs12Attributes = new Hashtable();
053 private Vector pkcs12Ordering = new Vector();
054
055 protected JCEDHPrivateKey()
056 {
057 }
058
059 JCEDHPrivateKey(
060 DHPrivateKey key)
061 {
062 this.x = key.getX();
063 this.dhSpec = key.getParams();
064 }
065
066 JCEDHPrivateKey(
067 DHPrivateKeySpec spec)
068 {
069 this.x = spec.getX();
070 this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
071 }
072
073 JCEDHPrivateKey(
074 PrivateKeyInfo info)
075 {
076 DHParameter params = new DHParameter((ASN1Sequence)info.getAlgorithmId().getParameters());
077 DERInteger derX = (DERInteger)info.getPrivateKey();
078
079 this.x = derX.getValue();
080 if (params.getL() != null)
081 {
082 this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue());
083 }
084 else
085 {
086 this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
087 }
088 }
089
090 JCEDHPrivateKey(
091 DHPrivateKeyParameters params)
092 {
093 this.x = params.getX();
094 this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG());
095 }
096
097 public String getAlgorithm()
098 {
099 return "DH";
100 }
101
102 /**
103 * return the encoding format we produce in getEncoded().
104 *
105 * @return the string "PKCS#8"
106 */
107 public String getFormat()
108 {
109 return "PKCS#8";
110 }
111
112 /**
113 * Return a PKCS8 representation of the key. The sequence returned
114 * represents a full PrivateKeyInfo object.
115 *
116 * @return a PKCS8 representation of the key.
117 */
118 public byte[] getEncoded()
119 {
120 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
121 DEROutputStream dOut = new DEROutputStream(bOut);
122 PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).getDERObject()), new DERInteger(getX()));
123
124 try
125 {
126 dOut.writeObject(info);
127 dOut.close();
128 }
129 catch (IOException e)
130 {
131 throw new RuntimeException("Error encoding DH private key", e);
132 }
133
134 return bOut.toByteArray();
135 }
136
137 public DHParameterSpec getParams()
138 {
139 return dhSpec;
140 }
141
142 public BigInteger getX()
143 {
144 return x;
145 }
146
147 private void readObject(
148 ObjectInputStream in)
149 throws IOException, ClassNotFoundException
150 {
151 x = (BigInteger)in.readObject();
152
153 this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt());
154 }
155
156 private void writeObject(
157 ObjectOutputStream out)
158 throws IOException
159 {
160 out.writeObject(this.getX());
161 out.writeObject(dhSpec.getP());
162 out.writeObject(dhSpec.getG());
163 out.writeInt(dhSpec.getL());
164 }
165
166 public void setBagAttribute(
167 DERObjectIdentifier oid,
168 DEREncodable attribute)
169 {
170 pkcs12Attributes.put(oid, attribute);
171 pkcs12Ordering.addElement(oid);
172 }
173
174 public DEREncodable getBagAttribute(
175 DERObjectIdentifier oid)
176 {
177 return (DEREncodable)pkcs12Attributes.get(oid);
178 }
179
180 public Enumeration getBagAttributeKeys()
181 {
182 return pkcs12Ordering.elements();
183 }
184 }