1
/* DHKeyPairPKCS8Codec.java -- PKCS#8 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)
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
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
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.DER;
52
import gnu.java.security.der.DERReader;
53
import gnu.java.security.der.DERValue;
54
import gnu.java.security.der.DERWriter;
55
import gnu.java.security.key.IKeyPairCodec;
56
import gnu.java.security.util.DerUtil;
57
import gnu.java.security.util.Util;
59
public class DHKeyPairPKCS8Codec
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()
72
* @throws InvalidParameterException ALWAYS.
74
public byte[] encodePublicKey(PublicKey key)
76
throw new InvalidParameterException("Wrong format for public keys");
80
* Returns the DER-encoded form of the PKCS#8 ASN.1 <i>PrivateKeyInfo</i>
81
* representation of a DH private key. The ASN.1 specification is as follows:
84
* PrivateKeyInfo ::= SEQUENCE {
85
* version INTEGER, -- MUST be 0
86
* privateKeyAlgorithm AlgorithmIdentifier,
87
* privateKey OCTET STRING
90
* AlgorithmIdentifier ::= SEQUENCE {
91
* algorithm OBJECT IDENTIFIER,
92
* parameters ANY DEFINED BY algorithm OPTIONAL
95
* DhParams ::= SEQUENCE {
96
* p INTEGER, -- odd prime, p=jq +1
97
* g INTEGER, -- generator, g
98
* q INTEGER -- factor of p-1
102
* @return the DER encoded form of the ASN.1 representation of the
103
* <i>PrivateKeyInfo</i> field in an X.509 certificate.
104
* @throw InvalidParameterException if an error occurs during the marshalling
107
public byte[] encodePrivateKey(PrivateKey key)
109
if (! (key instanceof GnuDHPrivateKey))
110
throw new InvalidParameterException("Wrong key type");
112
DERValue derVersion = new DERValue(DER.INTEGER, BigInteger.ZERO);
114
DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, DH_ALG_OID);
116
GnuDHPrivateKey pk = (GnuDHPrivateKey) key;
117
BigInteger p = pk.getParams().getP();
118
BigInteger g = pk.getParams().getG();
119
BigInteger q = pk.getQ();
120
BigInteger x = pk.getX();
122
ArrayList params = new ArrayList(3);
123
params.add(new DERValue(DER.INTEGER, p));
124
params.add(new DERValue(DER.INTEGER, g));
125
params.add(new DERValue(DER.INTEGER, q));
126
DERValue derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params);
128
ArrayList algorithmID = new ArrayList(2);
129
algorithmID.add(derOID);
130
algorithmID.add(derParams);
131
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
134
DERValue derPrivateKey = new DERValue(DER.OCTET_STRING, Util.trim(x));
136
ArrayList pki = new ArrayList(3);
138
pki.add(derAlgorithmID);
139
pki.add(derPrivateKey);
140
DERValue derPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, pki);
143
ByteArrayOutputStream baos = new ByteArrayOutputStream();
146
DERWriter.write(baos, derPKI);
147
result = baos.toByteArray();
149
catch (IOException e)
151
InvalidParameterException y = new InvalidParameterException();
160
* @throws InvalidParameterException ALWAYS.
162
public PublicKey decodePublicKey(byte[] input)
164
throw new InvalidParameterException("Wrong format for public keys");
168
* @param input the byte array to unmarshall into a valid DH
169
* {@link PrivateKey} instance. MUST NOT be null.
170
* @return a new instance of a {@link GnuDHPrivateKey} decoded from the
171
* <i>PrivateKeyInfo</i> material fed as <code>input</code>.
172
* @throw InvalidParameterException if an exception occurs during the
173
* unmarshalling process.
175
public PrivateKey decodePrivateKey(byte[] input)
178
throw new InvalidParameterException("Input bytes MUST NOT be null");
180
BigInteger version, p, q, g, x;
181
DERReader der = new DERReader(input);
184
DERValue derPKI = der.read();
185
DerUtil.checkIsConstructed(derPKI, "Wrong PrivateKeyInfo field");
187
DERValue derVersion = der.read();
188
if (! (derVersion.getValue() instanceof BigInteger))
189
throw new InvalidParameterException("Wrong Version field");
191
version = (BigInteger) derVersion.getValue();
192
if (version.compareTo(BigInteger.ZERO) != 0)
193
throw new InvalidParameterException("Unexpected Version: " + version);
195
DERValue derAlgoritmID = der.read();
196
DerUtil.checkIsConstructed(derAlgoritmID, "Wrong AlgorithmIdentifier field");
198
DERValue derOID = der.read();
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 DSS Parameters field");
206
DERValue val = der.read();
207
DerUtil.checkIsBigInteger(val, "Wrong P field");
208
p = (BigInteger) val.getValue();
210
DerUtil.checkIsBigInteger(val, "Wrong G field");
211
g = (BigInteger) val.getValue();
213
DerUtil.checkIsBigInteger(val, "Wrong Q field");
214
q = (BigInteger) val.getValue();
217
byte[] xBytes = (byte[]) val.getValue();
218
x = new BigInteger(1, xBytes);
220
catch (IOException e)
222
InvalidParameterException y = new InvalidParameterException();
227
return new GnuDHPrivateKey(Registry.PKCS8_ENCODING_ID, q, p, g, x);