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