Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / javax / crypto / key / dh / DHKeyPairX509Codec.java
blob7e8688bd3a40fcbd98443d0f988638f40de783fb
1 /* DHKeyPairX509Codec.java -- X.509 DER encoder/decoder for DH keys
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.javax.crypto.key.dh;
41 import java.io.ByteArrayOutputStream;
42 import java.io.IOException;
43 import java.math.BigInteger;
44 import java.security.InvalidParameterException;
45 import java.security.PrivateKey;
46 import java.security.PublicKey;
47 import java.util.ArrayList;
49 import gnu.java.security.OID;
50 import gnu.java.security.Registry;
51 import gnu.java.security.der.BitString;
52 import gnu.java.security.der.DER;
53 import gnu.java.security.der.DERReader;
54 import gnu.java.security.der.DERValue;
55 import gnu.java.security.der.DERWriter;
56 import gnu.java.security.key.IKeyPairCodec;
57 import gnu.java.security.util.DerUtil;
59 public class DHKeyPairX509Codec
60 implements IKeyPairCodec
62 private static final OID DH_ALG_OID = new OID(Registry.DH_OID_STRING);
64 // implicit 0-arguments constructor
66 public int getFormatID()
68 return X509_FORMAT;
71 /**
72 * Returns the DER-encoded form of the X.509 ASN.1 <i>SubjectPublicKeyInfo</i>
73 * representation of a DH public key. The ASN.1 specification, as defined in
74 * RFC-3280, and RFC-2459, is as follows:
76 * <pre>
77 * SubjectPublicKeyInfo ::= SEQUENCE {
78 * algorithm AlgorithmIdentifier,
79 * subjectPublicKey BIT STRING
80 * }
82 * AlgorithmIdentifier ::= SEQUENCE {
83 * algorithm OBJECT IDENTIFIER,
84 * parameters ANY DEFINED BY algorithm OPTIONAL
85 * }
87 * DhParams ::= SEQUENCE {
88 * p INTEGER, -- odd prime, p=jq +1
89 * g INTEGER, -- generator, g
90 * q INTEGER -- factor of p-1
91 * }
92 * </pre>
94 * <p>The <i>subjectPublicKey</i> field, which is a BIT STRING, contains the
95 * DER-encoded form of the DH public key as an INTEGER.</p>
97 * <pre>
98 * DHPublicKey ::= INTEGER -- public key, y = g^x mod p
99 * </pre>
101 * @param key the {@link PublicKey} instance to encode. MUST be an instance of
102 * {@link GnuDHPublicKey}.
103 * @return the DER-encoded form of the ASN.1 representation of the
104 * <i>SubjectPublicKeyInfo</i> in an X.509 certificate.
105 * @throw InvalidParameterException if <code>key</code> is not an instance
106 * of {@link GnuDHPublicKey} or if an exception occurs during the
107 * marshalling process.
109 public byte[] encodePublicKey(PublicKey key)
111 if (! (key instanceof GnuDHPublicKey))
112 throw new InvalidParameterException("Wrong key type");
114 DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, DH_ALG_OID);
116 GnuDHPublicKey dhKey = (GnuDHPublicKey) key;
117 BigInteger p = dhKey.getParams().getP();
118 BigInteger g = dhKey.getParams().getG();
119 BigInteger q = dhKey.getQ();
120 BigInteger y = dhKey.getY();
122 DERValue derP = new DERValue(DER.INTEGER, p);
123 DERValue derG = new DERValue(DER.INTEGER, g);
124 DERValue derQ = new DERValue(DER.INTEGER, q);
126 ArrayList params = new ArrayList(3);
127 params.add(derP);
128 params.add(derG);
129 params.add(derQ);
130 DERValue derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params);
132 ArrayList algorithmID = new ArrayList(2);
133 algorithmID.add(derOID);
134 algorithmID.add(derParams);
135 DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
136 algorithmID);
138 DERValue derDHPublicKey = new DERValue(DER.INTEGER, y);
139 byte[] yBytes = derDHPublicKey.getEncoded();
140 DERValue derSPK = new DERValue(DER.BIT_STRING, new BitString(yBytes));
142 ArrayList spki = new ArrayList(2);
143 spki.add(derAlgorithmID);
144 spki.add(derSPK);
145 DERValue derSPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, spki);
147 byte[] result;
148 ByteArrayOutputStream baos = new ByteArrayOutputStream();
151 DERWriter.write(baos, derSPKI);
152 result = baos.toByteArray();
154 catch (IOException x)
156 InvalidParameterException e = new InvalidParameterException();
157 e.initCause(x);
158 throw e;
161 return result;
165 * @throws InvalidParameterException ALWAYS.
167 public byte[] encodePrivateKey(PrivateKey key)
169 throw new InvalidParameterException("Wrong format for private keys");
173 * @param input the byte array to unmarshall into a valid DH
174 * {@link PublicKey} instance. MUST NOT be null.
175 * @return a new instance of a {@link GnuDHPublicKey} decoded from the
176 * <i>SubjectPublicKeyInfo</i> material in an X.509 certificate.
177 * @throw InvalidParameterException if an exception occurs during the
178 * unmarshalling process.
180 public PublicKey decodePublicKey(byte[] input)
182 if (input == null)
183 throw new InvalidParameterException("Input bytes MUST NOT be null");
185 BigInteger p, g, q, y;
186 DERReader der = new DERReader(input);
189 DERValue derSPKI = der.read();
190 DerUtil.checkIsConstructed(derSPKI, "Wrong SubjectPublicKeyInfo field");
192 DERValue derAlgorithmID = der.read();
193 DerUtil.checkIsConstructed(derAlgorithmID, "Wrong AlgorithmIdentifier field");
195 DERValue derOID = der.read();
196 if (! (derOID.getValue() instanceof OID))
197 throw new InvalidParameterException("Wrong Algorithm field");
199 OID algOID = (OID) derOID.getValue();
200 if (! algOID.equals(DH_ALG_OID))
201 throw new InvalidParameterException("Unexpected OID: " + algOID);
203 DERValue derParams = der.read();
204 DerUtil.checkIsConstructed(derParams, "Wrong DH Parameters field");
206 DERValue val = der.read();
207 DerUtil.checkIsBigInteger(val, "Wrong P field");
208 p = (BigInteger) val.getValue();
209 val = der.read();
210 DerUtil.checkIsBigInteger(val, "Wrong G field");
211 g = (BigInteger) val.getValue();
212 val = der.read();
213 DerUtil.checkIsBigInteger(val, "Wrong Q field");
214 q = (BigInteger) val.getValue();
216 val = der.read();
217 if (! (val.getValue() instanceof BitString))
218 throw new InvalidParameterException("Wrong SubjectPublicKey field");
220 byte[] yBytes = ((BitString) val.getValue()).toByteArray();
222 DERReader dhPub = new DERReader(yBytes);
223 val = dhPub.read();
224 DerUtil.checkIsBigInteger(val, "Wrong Y field");
225 y = (BigInteger) val.getValue();
227 catch (IOException x)
229 InvalidParameterException e = new InvalidParameterException();
230 e.initCause(x);
231 throw e;
234 return new GnuDHPublicKey(Registry.X509_ENCODING_ID, q, p, g, y);
238 * @throws InvalidParameterException ALWAYS.
240 public PrivateKey decodePrivateKey(byte[] input)
242 throw new InvalidParameterException("Wrong format for private keys");