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