Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.installer / org.gvsig.installer.lib / org.gvsig.installer.lib.impl / src / main / java / org / gvsig / installer / lib / impl / utils / SignUtil.java @ 40560

History | View | Annotate | Download (9.37 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.installer.lib.impl.utils;
25

    
26
import java.io.BufferedReader;
27
import java.io.File;
28
import java.io.FileInputStream;
29
import java.io.FileNotFoundException;
30
import java.io.FileOutputStream;
31
import java.io.FileWriter;
32
import java.io.InputStream;
33
import java.io.StringReader;
34
import java.io.StringWriter;
35
import java.security.KeyFactory;
36
import java.security.KeyPair;
37
import java.security.KeyPairGenerator;
38
import java.security.NoSuchAlgorithmException;
39
import java.security.NoSuchProviderException;
40
import java.security.PrivateKey;
41
import java.security.PublicKey;
42
import java.security.SecureRandom;
43
import java.security.Signature;
44
import java.security.spec.EncodedKeySpec;
45
import java.security.spec.InvalidKeySpecException;
46
import java.security.spec.PKCS8EncodedKeySpec;
47
import java.security.spec.X509EncodedKeySpec;
48

    
49
import org.apache.commons.codec.binary.Base64;
50

    
51
public class SignUtil {
52

    
53
        public static final int SIGN_OK = 0;
54
        public static final int SIGN_FAIL = 1;
55
        public static final int NOT_SIGNED = 2;
56

    
57
        private PublicKey pubKey = null;
58
        private PrivateKey privKey = null;
59

    
60
        public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, FileNotFoundException {
61
                new SignUtil().doMain(args);
62
        }
63

    
64
        private void doMain(String[] args) {
65

    
66
                try {
67
                        if( "sign".equalsIgnoreCase(getCommand(args)) ) {
68
                                if( !this.canSign() ) {
69
                                        System.out.println("Can't locate private key to sign.");
70
                                        return;
71
                                }
72
                                this.sign( this.getArg1AsFile(args));
73
                                System.out.println("File "+this.getArg1(args)+" signed.");
74
                                return;
75
                        }
76
                        
77
                        if( "verify".equalsIgnoreCase(getCommand(args)) ) {
78
                                if( !this.canVerify() ) {
79
                                        System.out.println("Can't locate public key to verify.");
80
                                        return;
81
                                }
82
                                switch(this.verify(this.getArg1AsFile(args))) {
83
                                case NOT_SIGNED:
84
                                        System.out.println("NOT SIGNED");
85
                                        break;
86
                                case SIGN_FAIL:
87
                                        System.out.println("SIGN FAIL");
88
                                        break;
89
                                case SIGN_OK:
90
                                        System.out.println("SIGN OK");
91
                                        break;
92
                                default:
93
                                        System.out.println("ERROR");
94
                                }
95
                                return;
96
                        }
97

    
98
                        if( "generateKeys".equalsIgnoreCase(getCommand(args)) ) {
99
                                this.generateKeys();
100
                                System.out.println("Generate keys ok");
101
                                return;
102
                        }
103

    
104
                        System.out.println("Usage: SignUtil sign|verify|generateKeys\n" +
105
                                        "  sign file\n" +
106
                                        "  verify file\n" +
107
                                        "  generateKeys\n");
108
                        return;
109
                } catch (Exception e) {
110
                        e.printStackTrace();
111
                }
112
        }
113
        
114
        private String getCommand(String[] args) {
115
                if( args.length>=1) {
116
                        return args[0];
117
                }
118
                return null;
119
        }
120
        
121
        private File getArg1AsFile(String[] args) {
122
                if( args.length>=2) {
123
                        return new File(args[1]);
124
                }
125
                return null;
126
        }
127
        
128
        private String getArg1(String[] args) {
129
                if( args.length>=2) {
130
                        return args[1];
131
                }
132
                return null;
133
        }
134
        
135
        public SignUtil()  {
136
                loadPrivateKey();
137
                loadPublicKey();
138
        }
139

    
140
        public SignUtil(byte[] publicKey){
141
                loadPrivateKey();
142
                loadPublicKey(publicKey);
143
        }
144

    
145
        private void loadPrivateKey()  {
146
                File home = new File(System.getProperty("user.home"));
147
                File keyfile = new File(home, ".gvsig-keys" + File.separatorChar
148
                                + "key.private");
149
                if (keyfile.exists()) {
150
                        try {
151
                                loadPrivateKey(keyfile);
152
                        } catch (Exception e) {
153
                                // Ignore errors
154
                        }
155
                }
156
        }
157

    
158
        private PrivateKey loadPrivateKey(File key) {
159
                try {
160
                        byte[] rawkey;
161
                        rawkey = loadFileAsByteArray(new FileInputStream(key));
162
                        EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawkey);
163
                        KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN");
164
                        this.privKey = keyFactory.generatePrivate(keySpec);
165
                } catch (Exception e) {
166
                        this.privKey = null;
167
                }
168
                return this.privKey;
169
        }
170

    
171
        private PublicKey loadPublicKey() {
172
                File home = new File(System.getProperty("user.home"));
173
                File keyfile = new File(home, ".gvsig-keys" + File.separatorChar
174
                                + "key.public");
175
                if (keyfile.exists()) {
176
                                return loadPublicKey(loadFileAsByteArray(keyfile));
177
                }
178
                return null;
179
        }
180
        private PublicKey loadPublicKey(byte[] rawkey)  {
181
                try {
182
                        EncodedKeySpec keySpec = new X509EncodedKeySpec(rawkey);
183
                        KeyFactory keyFactory;
184
                        keyFactory = KeyFactory.getInstance("DSA", "SUN");
185
                        this.pubKey = keyFactory.generatePublic(keySpec);
186
                } catch (Exception e) {
187
                        this.pubKey = null;
188
                }
189
                return this.pubKey;
190
        }
191

    
192
        private PublicKey getPublicKey() {
193
                return this.pubKey;
194
        }
195

    
196
        private PrivateKey getPrivateKey() {
197
                return this.privKey;
198
        }
199

    
200
        private byte[] loadFileAsByteArray(InputStream in) {
201
                byte[] alldata;
202
                try {
203
                        alldata = new byte[in.available()];
204
                        in.read(alldata);
205
                        in.close();
206
                } catch (Exception e) {
207
                        e.printStackTrace();
208
                        return null;
209
                }
210
                return alldata;
211
        }
212

    
213
        private byte[] loadFileAsByteArray(File file) {
214
                try {
215
                        return loadFileAsByteArray(new FileInputStream(file));
216
                } catch (FileNotFoundException e) {
217
                        e.printStackTrace();
218
                        return null;
219
                }
220
        }
221

    
222
        private String getData(byte[] alldata) {
223
                BufferedReader reader = new BufferedReader(new StringReader(
224
                                new String(alldata)));
225
                StringWriter writer = new StringWriter();
226
                String line;
227
                try {
228
                        boolean inSignature = false;
229
                        while ((line = reader.readLine()) != null) {
230
                                if (inSignature) {
231
                                        if (line.startsWith("## END SIGNATURE")) {
232
                                                inSignature = false;
233
                                        }
234
                                } else {
235
                                        if (line.startsWith("## BEGIN SIGNATURE")) {
236
                                                inSignature = true;
237
                                        } else {
238
                                                writer.append(line);
239
                                                writer.append("\n");
240
                                        }
241
                                }
242
                        }
243
                        writer.close();
244
                } catch (Exception e) {
245
                        e.printStackTrace();
246
                        return null;
247
                }
248
                return writer.toString();
249
        }
250

    
251
        private byte[] getSignature(byte[] alldata) {
252
                BufferedReader reader = new BufferedReader(new StringReader(
253
                                new String(alldata)));
254
                StringWriter writer = new StringWriter();
255
                String line;
256
                try {
257
                        boolean inSignature = false;
258
                        while ((line = reader.readLine()) != null) {
259
                                if (inSignature) {
260
                                        if (line.startsWith("## END SIGNATURE")) {
261
                                                inSignature = false;
262
                                        } else {
263
                                                writer.append(line);
264
                                                writer.append("\n");
265
                                        }
266
                                } else {
267
                                        if (line.startsWith("## BEGIN SIGNATURE")) {
268
                                                inSignature = true;
269
                                        }
270
                                }
271
                        }
272
                        writer.close();
273
                } catch (Exception e) {
274
                        e.printStackTrace();
275
                        return null;
276
                }
277
                String s = writer.toString();
278
                if (s.length() < 1) {
279
                        return null;
280
                }
281
                Base64 coder = new Base64(60);
282
                return coder.decode(s);
283
        }
284

    
285
        public void sign(File file) {
286
                Signature dsa;
287
                Base64 coder = new Base64(60);
288

    
289
                try {
290
                        String data = getData(loadFileAsByteArray(file));
291
                        dsa = Signature.getInstance("SHA1withDSA", "SUN");
292
                        dsa.initSign(getPrivateKey());
293
                        dsa.update(data.getBytes());
294

    
295
                        String sig = coder.encodeAsString(dsa.sign());
296
                        String[] lines = sig.split("\n");
297

    
298
                        FileWriter fw = new FileWriter(file);
299
                        fw.append(data);
300
                        fw.append("## BEGIN SIGNATURE\n");
301
                        for (int i = 0; i < lines.length; i++) {
302
                                fw.append("## ");
303
                                fw.append(lines[i]);
304
                                fw.append("\n");
305
                        }
306
                        fw.append("## END SIGNATURE\n");
307
                        fw.close();
308

    
309
                } catch (Exception e) {
310
                        e.printStackTrace();
311
                }
312

    
313
        }
314
        
315
        public int verify(File file) {
316
                return verify(loadFileAsByteArray(file));
317
        }
318

    
319
        public int verify(byte[] alldata) {
320
                try {
321
                        String data = getData(alldata);
322
                        byte[] signature = getSignature(alldata);
323
                        if (signature == null) {
324
                                return NOT_SIGNED;
325
                        }
326
                        Signature dsa;
327
                        dsa = Signature.getInstance("SHA1withDSA", "SUN");
328
                        dsa.initVerify(getPublicKey());
329
                        dsa.update(data.getBytes());
330
                        if (!dsa.verify(signature)) {
331
                                return SIGN_FAIL;
332
                        }
333
                        return SIGN_OK;
334

    
335
                } catch (Exception e) {
336
                        e.printStackTrace();
337
                }
338
                return NOT_SIGNED;
339
        }
340

    
341
        public void generateKeys() {
342
                try {
343
                        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA",
344
                                        "SUN");
345
                        SecureRandom random = SecureRandom.getInstance("SHA1PRNG",
346
                                        "SUN");
347
                        keyGen.initialize(1024, random);
348

    
349
                        KeyPair pair = keyGen.generateKeyPair();
350
                        PrivateKey privKey = pair.getPrivate();
351
                        PublicKey pubKey = pair.getPublic();
352

    
353
                        FileOutputStream fos;
354
                        fos = new FileOutputStream("key.private");
355
                        fos.write(privKey.getEncoded());
356
                        fos.close();
357

    
358
                        fos = new FileOutputStream("key.public");
359
                        fos.write(pubKey.getEncoded());
360
                        fos.close();
361

    
362
                        System.out
363
                                        .println("Generados los ficheros key.private y key.public en la carpeta corriente.");
364
                        System.out
365
                                        .println("Por defecto la aplicaccion las buscara en la carpeta $HOME/.gvsig-keys .");
366
                } catch (Exception e) {
367
                        e.printStackTrace();
368
                }
369

    
370
        }
371
        
372
        public boolean canSign() {
373
                if( this.getPrivateKey() == null ) {
374
                        return false;
375
                }
376
                return true;
377
        }
378
        
379
        public boolean canVerify() {
380
                if( this.getPublicKey() == null ) {
381
                        return false;
382
                }
383
                return true;
384
        }
385
        
386
        
387
}