Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / org.gvsig.installer / org.gvsig.installer.lib / org.gvsig.installer.lib.impl / src / main / java / org / gvsig / installer / lib / impl / utils / SignUtil.java @ 37857

History | View | Annotate | Download (8.43 KB)

1
package org.gvsig.installer.lib.impl.utils;
2

    
3
import java.io.BufferedReader;
4
import java.io.File;
5
import java.io.FileInputStream;
6
import java.io.FileNotFoundException;
7
import java.io.FileOutputStream;
8
import java.io.FileWriter;
9
import java.io.InputStream;
10
import java.io.StringReader;
11
import java.io.StringWriter;
12
import java.security.KeyFactory;
13
import java.security.KeyPair;
14
import java.security.KeyPairGenerator;
15
import java.security.NoSuchAlgorithmException;
16
import java.security.NoSuchProviderException;
17
import java.security.PrivateKey;
18
import java.security.PublicKey;
19
import java.security.SecureRandom;
20
import java.security.Signature;
21
import java.security.spec.EncodedKeySpec;
22
import java.security.spec.InvalidKeySpecException;
23
import java.security.spec.PKCS8EncodedKeySpec;
24
import java.security.spec.X509EncodedKeySpec;
25

    
26
import org.apache.commons.codec.binary.Base64;
27

    
28
public class SignUtil {
29

    
30
        public static final int SIGN_OK = 0;
31
        public static final int SIGN_FAIL = 1;
32
        public static final int NOT_SIGNED = 2;
33

    
34
        private PublicKey pubKey = null;
35
        private PrivateKey privKey = null;
36

    
37
        public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, FileNotFoundException {
38
                new SignUtil().doMain(args);
39
        }
40

    
41
        private void doMain(String[] args) {
42

    
43
                try {
44
                        if( "sign".equalsIgnoreCase(getCommand(args)) ) {
45
                                if( !this.canSign() ) {
46
                                        System.out.println("Can't locate private key to sign.");
47
                                        return;
48
                                }
49
                                this.sign( this.getArg1AsFile(args));
50
                                System.out.println("File "+this.getArg1(args)+" signed.");
51
                                return;
52
                        }
53
                        
54
                        if( "verify".equalsIgnoreCase(getCommand(args)) ) {
55
                                if( !this.canVerify() ) {
56
                                        System.out.println("Can't locate public key to verify.");
57
                                        return;
58
                                }
59
                                switch(this.verify(this.getArg1AsFile(args))) {
60
                                case NOT_SIGNED:
61
                                        System.out.println("NOT SIGNED");
62
                                        break;
63
                                case SIGN_FAIL:
64
                                        System.out.println("SIGN FAIL");
65
                                        break;
66
                                case SIGN_OK:
67
                                        System.out.println("SIGN OK");
68
                                        break;
69
                                default:
70
                                        System.out.println("ERROR");
71
                                }
72
                                return;
73
                        }
74

    
75
                        if( "generateKeys".equalsIgnoreCase(getCommand(args)) ) {
76
                                this.generateKeys();
77
                                System.out.println("Generate keys ok");
78
                                return;
79
                        }
80

    
81
                        System.out.println("Usage: SignUtil sign|verify|generateKeys\n" +
82
                                        "  sign file\n" +
83
                                        "  verify file\n" +
84
                                        "  generateKeys\n");
85
                        return;
86
                } catch (Exception e) {
87
                        e.printStackTrace();
88
                }
89
        }
90
        
91
        private String getCommand(String[] args) {
92
                if( args.length>=1) {
93
                        return args[0];
94
                }
95
                return null;
96
        }
97
        
98
        private File getArg1AsFile(String[] args) {
99
                if( args.length>=2) {
100
                        return new File(args[1]);
101
                }
102
                return null;
103
        }
104
        
105
        private String getArg1(String[] args) {
106
                if( args.length>=2) {
107
                        return args[1];
108
                }
109
                return null;
110
        }
111
        
112
        public SignUtil()  {
113
                loadPrivateKey();
114
                loadPublicKey();
115
        }
116

    
117
        public SignUtil(byte[] publicKey){
118
                loadPrivateKey();
119
                loadPublicKey(publicKey);
120
        }
121

    
122
        private void loadPrivateKey()  {
123
                File home = new File(System.getProperty("user.home"));
124
                File keyfile = new File(home, ".gvsig-keys" + File.separatorChar
125
                                + "key.private");
126
                if (keyfile.exists()) {
127
                        try {
128
                                loadPrivateKey(keyfile);
129
                        } catch (Exception e) {
130
                                // Ignore errors
131
                        }
132
                }
133
        }
134

    
135
        private PrivateKey loadPrivateKey(File key) {
136
                try {
137
                        byte[] rawkey;
138
                        rawkey = loadFileAsByteArray(new FileInputStream(key));
139
                        EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawkey);
140
                        KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN");
141
                        this.privKey = keyFactory.generatePrivate(keySpec);
142
                } catch (Exception e) {
143
                        this.privKey = null;
144
                }
145
                return this.privKey;
146
        }
147

    
148
        private PublicKey loadPublicKey() {
149
                File home = new File(System.getProperty("user.home"));
150
                File keyfile = new File(home, ".gvsig-keys" + File.separatorChar
151
                                + "key.public");
152
                if (keyfile.exists()) {
153
                                return loadPublicKey(loadFileAsByteArray(keyfile));
154
                }
155
                return null;
156
        }
157
        private PublicKey loadPublicKey(byte[] rawkey)  {
158
                try {
159
                        EncodedKeySpec keySpec = new X509EncodedKeySpec(rawkey);
160
                        KeyFactory keyFactory;
161
                        keyFactory = KeyFactory.getInstance("DSA", "SUN");
162
                        this.pubKey = keyFactory.generatePublic(keySpec);
163
                } catch (Exception e) {
164
                        this.pubKey = null;
165
                }
166
                return this.pubKey;
167
        }
168

    
169
        private PublicKey getPublicKey() {
170
                return this.pubKey;
171
        }
172

    
173
        private PrivateKey getPrivateKey() {
174
                return this.privKey;
175
        }
176

    
177
        private byte[] loadFileAsByteArray(InputStream in) {
178
                byte[] alldata;
179
                try {
180
                        alldata = new byte[in.available()];
181
                        in.read(alldata);
182
                        in.close();
183
                } catch (Exception e) {
184
                        e.printStackTrace();
185
                        return null;
186
                }
187
                return alldata;
188
        }
189

    
190
        private byte[] loadFileAsByteArray(File file) {
191
                try {
192
                        return loadFileAsByteArray(new FileInputStream(file));
193
                } catch (FileNotFoundException e) {
194
                        e.printStackTrace();
195
                        return null;
196
                }
197
        }
198

    
199
        private String getData(byte[] alldata) {
200
                BufferedReader reader = new BufferedReader(new StringReader(
201
                                new String(alldata)));
202
                StringWriter writer = new StringWriter();
203
                String line;
204
                try {
205
                        boolean inSignature = false;
206
                        while ((line = reader.readLine()) != null) {
207
                                if (inSignature) {
208
                                        if (line.startsWith("## END SIGNATURE")) {
209
                                                inSignature = false;
210
                                        }
211
                                } else {
212
                                        if (line.startsWith("## BEGIN SIGNATURE")) {
213
                                                inSignature = true;
214
                                        } else {
215
                                                writer.append(line);
216
                                                writer.append("\n");
217
                                        }
218
                                }
219
                        }
220
                        writer.close();
221
                } catch (Exception e) {
222
                        e.printStackTrace();
223
                        return null;
224
                }
225
                return writer.toString();
226
        }
227

    
228
        private byte[] getSignature(byte[] alldata) {
229
                BufferedReader reader = new BufferedReader(new StringReader(
230
                                new String(alldata)));
231
                StringWriter writer = new StringWriter();
232
                String line;
233
                try {
234
                        boolean inSignature = false;
235
                        while ((line = reader.readLine()) != null) {
236
                                if (inSignature) {
237
                                        if (line.startsWith("## END SIGNATURE")) {
238
                                                inSignature = false;
239
                                        } else {
240
                                                writer.append(line);
241
                                                writer.append("\n");
242
                                        }
243
                                } else {
244
                                        if (line.startsWith("## BEGIN SIGNATURE")) {
245
                                                inSignature = true;
246
                                        }
247
                                }
248
                        }
249
                        writer.close();
250
                } catch (Exception e) {
251
                        e.printStackTrace();
252
                        return null;
253
                }
254
                String s = writer.toString();
255
                if (s.length() < 1) {
256
                        return null;
257
                }
258
                Base64 coder = new Base64(60);
259
                return coder.decode(s);
260
        }
261

    
262
        public void sign(File file) {
263
                Signature dsa;
264
                Base64 coder = new Base64(60);
265

    
266
                try {
267
                        String data = getData(loadFileAsByteArray(file));
268
                        dsa = Signature.getInstance("SHA1withDSA", "SUN");
269
                        dsa.initSign(getPrivateKey());
270
                        dsa.update(data.getBytes());
271

    
272
                        String sig = coder.encodeAsString(dsa.sign());
273
                        String[] lines = sig.split("\n");
274

    
275
                        FileWriter fw = new FileWriter(file);
276
                        fw.append(data);
277
                        fw.append("## BEGIN SIGNATURE\n");
278
                        for (int i = 0; i < lines.length; i++) {
279
                                fw.append("## ");
280
                                fw.append(lines[i]);
281
                                fw.append("\n");
282
                        }
283
                        fw.append("## END SIGNATURE\n");
284
                        fw.close();
285

    
286
                } catch (Exception e) {
287
                        e.printStackTrace();
288
                }
289

    
290
        }
291
        
292
        public int verify(File file) {
293
                return verify(loadFileAsByteArray(file));
294
        }
295

    
296
        public int verify(byte[] alldata) {
297
                try {
298
                        String data = getData(alldata);
299
                        byte[] signature = getSignature(alldata);
300
                        if (signature == null) {
301
                                return NOT_SIGNED;
302
                        }
303
                        Signature dsa;
304
                        dsa = Signature.getInstance("SHA1withDSA", "SUN");
305
                        dsa.initVerify(getPublicKey());
306
                        dsa.update(data.getBytes());
307
                        if (!dsa.verify(signature)) {
308
                                return SIGN_FAIL;
309
                        }
310
                        return SIGN_OK;
311

    
312
                } catch (Exception e) {
313
                        e.printStackTrace();
314
                }
315
                return NOT_SIGNED;
316
        }
317

    
318
        public void generateKeys() {
319
                try {
320
                        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA",
321
                                        "SUN");
322
                        SecureRandom random = SecureRandom.getInstance("SHA1PRNG",
323
                                        "SUN");
324
                        keyGen.initialize(1024, random);
325

    
326
                        KeyPair pair = keyGen.generateKeyPair();
327
                        PrivateKey privKey = pair.getPrivate();
328
                        PublicKey pubKey = pair.getPublic();
329

    
330
                        FileOutputStream fos;
331
                        fos = new FileOutputStream("key.private");
332
                        fos.write(privKey.getEncoded());
333
                        fos.close();
334

    
335
                        fos = new FileOutputStream("key.public");
336
                        fos.write(pubKey.getEncoded());
337
                        fos.close();
338

    
339
                        System.out
340
                                        .println("Generados los ficheros key.private y key.public en la carpeta corriente.");
341
                        System.out
342
                                        .println("Por defecto la aplicaccion las buscara en la carpeta $HOME/.gvsig-keys .");
343
                } catch (Exception e) {
344
                        e.printStackTrace();
345
                }
346

    
347
        }
348
        
349
        public boolean canSign() {
350
                if( this.getPrivateKey() == null ) {
351
                        return false;
352
                }
353
                return true;
354
        }
355
        
356
        public boolean canVerify() {
357
                if( this.getPublicKey() == null ) {
358
                        return false;
359
                }
360
                return true;
361
        }
362
        
363
        
364
}