001package com.hfg.security;
002
003import java.io.*;
004import java.security.*;
005import java.security.spec.X509EncodedKeySpec;
006import java.security.spec.PKCS8EncodedKeySpec;
007
008
009//------------------------------------------------------------------------------
010/**
011 * DSA-related functions.
012 *
013 * @author J. Alex Taylor, hairyfatguy.com
014 */
015//------------------------------------------------------------------------------
016// com.hfg XML/HTML Coding Library
017//
018// This library is free software; you can redistribute it and/or
019// modify it under the terms of the GNU Lesser General Public
020// License as published by the Free Software Foundation; either
021// version 2.1 of the License, or (at your option) any later version.
022//
023// This library is distributed in the hope that it will be useful,
024// but WITHOUT ANY WARRANTY; without even the implied warranty of
025// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
026// Lesser General Public License for more details.
027//
028// You should have received a copy of the GNU Lesser General Public
029// License along with this library; if not, write to the Free Software
030// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
031//
032// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
033// jataylor@hairyfatguy.com
034//------------------------------------------------------------------------------
035
036public class DSAUtil
037{
038   //--------------------------------------------------------------------------
039   public static void generateDSAKeyPair(File inOutputDir)
040   {
041      try
042      {
043         KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
044
045         SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
046         keyGen.initialize(1024, random);
047
048         KeyPair pair = keyGen.generateKeyPair();
049         PrivateKey priv = pair.getPrivate();
050         PublicKey pub = pair.getPublic();
051
052         // Save the public key in a file
053         byte[] key = pub.getEncoded();
054         FileOutputStream keyfos = new FileOutputStream(new File(inOutputDir, "DSAKey.pub"));
055         keyfos.write(key);
056         keyfos.close();
057
058         // Save the private key in a file
059         key = priv.getEncoded();
060         keyfos = new FileOutputStream(new File(inOutputDir, "DSAKey.priv"));
061         keyfos.write(key);
062         keyfos.close();
063      }
064      catch (Exception e)
065      {
066         throw new RuntimeException(e);
067      }
068   }
069
070   //--------------------------------------------------------------------------
071   public static byte[] signData(PrivateKey inPrivateKey, byte[] inData)
072   {
073      return signData(inPrivateKey, new ByteArrayInputStream(inData));
074   }
075
076   //--------------------------------------------------------------------------
077   public static byte[] signData(PrivateKey inPrivateKey, InputStream inData)
078   {
079      byte[] sig;
080      try
081      {
082         try
083         {
084            Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
085            dsa.initSign(inPrivateKey);
086
087            byte[] buffer = new byte[1024];
088            int len;
089            while (inData.available() != 0)
090            {
091               len = inData.read(buffer);
092               dsa.update(buffer, 0, len);
093            }
094
095            sig = dsa.sign();
096         }
097         finally
098         {
099            if (inData != null) inData.close();
100         }
101      }
102      catch (Exception e)
103      {
104         throw new RuntimeException(e);
105      }
106
107      return sig;
108   }
109
110
111   //--------------------------------------------------------------------------
112   public static boolean verifySignature(PublicKey inPublicKey, byte[] inData, byte[] inSignature)
113   {
114      return verifySignature(inPublicKey, new ByteArrayInputStream(inData), inSignature);
115   }
116
117   //--------------------------------------------------------------------------
118   public static boolean verifySignature(PublicKey inPublicKey, InputStream inData, byte[] inSignature)
119   {
120      boolean result = false;
121      try
122      {
123         try
124         {
125            Signature sig = Signature.getInstance("SHA1withDSA", "SUN");
126            sig.initVerify(inPublicKey);
127
128            byte[] buffer = new byte[1024];
129            int len;
130            while (inData.available() != 0)
131            {
132               len = inData.read(buffer);
133               sig.update(buffer, 0, len);
134            }
135
136            result = sig.verify(inSignature);
137         }
138         finally
139         {
140            if (inData != null) inData.close();
141         }
142      }
143      catch (Exception e)
144      {
145         throw new RuntimeException(e);
146      }
147
148      return result;
149   }
150
151   //--------------------------------------------------------------------------
152   public static PublicKey readPublicKey(File inX509EncodedPublicKeyFile)
153   {
154      byte[] encKey;
155
156      try
157      {
158         FileInputStream keyfis = new FileInputStream(inX509EncodedPublicKeyFile);
159         encKey = new byte[keyfis.available()];
160         keyfis.read(encKey);
161         keyfis.close();
162      }
163      catch (Exception e)
164      {
165         throw new RuntimeException(e);
166      }
167
168      return readPublicKey(encKey);
169   }
170
171   //--------------------------------------------------------------------------
172   public static PublicKey readPublicKey(InputStream inX509EncodedPublicKeyStream)
173   {
174      byte[] encKey;
175
176      try
177      {
178         try
179         {
180            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
181            byte[] buffer = new byte[1024];
182            int len;
183            while ((len = inX509EncodedPublicKeyStream.read(buffer)) != -1)
184            {
185               outStream.write(buffer, 0, len);
186            }
187
188            outStream.close();
189            encKey = outStream.toByteArray();
190         }
191         finally
192         {
193            inX509EncodedPublicKeyStream.close();
194         }
195      }
196      catch (Exception e)
197      {
198         throw new RuntimeException(e);
199      }
200
201      return readPublicKey(encKey);
202   }
203
204   //--------------------------------------------------------------------------
205   public static PublicKey readPublicKey(byte[] inX509EncodedPublicKey)
206   {
207      PublicKey pubKey;
208
209      try
210      {
211         X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(inX509EncodedPublicKey);
212         KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN");
213         pubKey = keyFactory.generatePublic(pubKeySpec);
214      }
215      catch (Exception e)
216      {
217         throw new RuntimeException(e);
218      }
219
220      return pubKey;
221   }
222
223
224   //--------------------------------------------------------------------------
225   public static PrivateKey readPrivateKey(File inPKCS8EncodedPrivateKeyFile)
226   {
227      byte[] encKey;
228
229      try
230      {
231         FileInputStream keyfis = new FileInputStream(inPKCS8EncodedPrivateKeyFile);
232         encKey = new byte[keyfis.available()];
233         keyfis.read(encKey);
234         keyfis.close();
235      }
236      catch (Exception e)
237      {
238         throw new RuntimeException(e);
239      }
240
241      return readPrivateKey(encKey);
242   }
243
244
245   //--------------------------------------------------------------------------
246   public static PrivateKey readPrivateKey(InputStream inPKCS8EncodedPrivateKeyStream)
247   {
248      byte[] encKey = null;
249
250      if (inPKCS8EncodedPrivateKeyStream != null)
251      {
252         try
253         {
254            try
255            {
256               ByteArrayOutputStream outStream = new ByteArrayOutputStream();
257               byte[] buffer = new byte[1024];
258               int len;
259               while ((len = inPKCS8EncodedPrivateKeyStream.read(buffer)) != -1)
260               {
261                  outStream.write(buffer, 0, len);
262               }
263
264               outStream.close();
265               encKey = outStream.toByteArray();
266            }
267            finally
268            {
269               inPKCS8EncodedPrivateKeyStream.close();
270            }
271         }
272         catch (Exception e)
273         {
274            throw new RuntimeException(e);
275         }
276      }
277
278      return readPrivateKey(encKey);
279   }
280
281   //--------------------------------------------------------------------------
282   public static PrivateKey readPrivateKey(byte[] inPKCS8EncodedPrivateKey)
283   {
284      PrivateKey privKey = null;
285
286      if (inPKCS8EncodedPrivateKey != null)
287      {
288         try
289         {
290            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(inPKCS8EncodedPrivateKey);
291            KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN");
292            privKey = keyFactory.generatePrivate(keySpec);
293         }
294         catch (Exception e)
295         {
296            throw new RuntimeException(e);
297         }
298      }
299
300      return privKey;
301   }
302}