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
026 import javax.crypto.interfaces.DHPublicKey;
027 import javax.crypto.spec.DHParameterSpec;
028 import javax.crypto.spec.DHPublicKeySpec;
029
030 import org.apache.geronimo.util.asn1.ASN1Sequence;
031 import org.apache.geronimo.util.asn1.DERInteger;
032 import org.apache.geronimo.util.asn1.DEROutputStream;
033 import org.apache.geronimo.util.asn1.pkcs.DHParameter;
034 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier;
035 import org.apache.geronimo.util.asn1.x509.SubjectPublicKeyInfo;
036 import org.apache.geronimo.util.asn1.x9.X9ObjectIdentifiers;
037 import org.apache.geronimo.util.crypto.params.DHPublicKeyParameters;
038
039 public class JCEDHPublicKey
040 implements DHPublicKey
041 {
042 private BigInteger y;
043 private DHParameterSpec dhSpec;
044
045 JCEDHPublicKey(
046 DHPublicKeySpec spec)
047 {
048 this.y = spec.getY();
049 this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
050 }
051
052 JCEDHPublicKey(
053 DHPublicKey key)
054 {
055 this.y = key.getY();
056 this.dhSpec = key.getParams();
057 }
058
059 JCEDHPublicKey(
060 DHPublicKeyParameters params)
061 {
062 this.y = params.getY();
063 this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), 0);
064 }
065
066 JCEDHPublicKey(
067 BigInteger y,
068 DHParameterSpec dhSpec)
069 {
070 this.y = y;
071 this.dhSpec = dhSpec;
072 }
073
074 JCEDHPublicKey(
075 SubjectPublicKeyInfo info)
076 {
077 DHParameter params = new DHParameter((ASN1Sequence)info.getAlgorithmId().getParameters());
078 DERInteger derY = null;
079
080 try
081 {
082 derY = (DERInteger)info.getPublicKey();
083 }
084 catch (IOException e)
085 {
086 throw new IllegalArgumentException("invalid info structure in DH public key", e);
087 }
088
089 this.y = derY.getValue();
090 if (params.getL() != null)
091 {
092 this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue());
093 }
094 else
095 {
096 this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
097 }
098 }
099
100 public String getAlgorithm()
101 {
102 return "DH";
103 }
104
105 public String getFormat()
106 {
107 return "X.509";
108 }
109
110 public byte[] getEncoded()
111 {
112 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
113 DEROutputStream dOut = new DEROutputStream(bOut);
114 SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.dhpublicnumber, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).getDERObject()), new DERInteger(y));
115
116 try
117 {
118 dOut.writeObject(info);
119 dOut.close();
120 }
121 catch (IOException e)
122 {
123 throw new RuntimeException("Error encoding DH public key", e);
124 }
125
126 return bOut.toByteArray();
127
128 }
129
130 public DHParameterSpec getParams()
131 {
132 return dhSpec;
133 }
134
135 public BigInteger getY()
136 {
137 return y;
138 }
139
140 private void readObject(
141 ObjectInputStream in)
142 throws IOException, ClassNotFoundException
143 {
144 this.y = (BigInteger)in.readObject();
145 this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt());
146 }
147
148 private void writeObject(
149 ObjectOutputStream out)
150 throws IOException
151 {
152 out.writeObject(this.getY());
153 out.writeObject(dhSpec.getP());
154 out.writeObject(dhSpec.getG());
155 out.writeInt(dhSpec.getL());
156 }
157 }