1 /*
2  * Created on 13 Jun 2006
3  * Created by Paul Gardner
4  * Copyright (C) Azureus Software, Inc, All Rights Reserved.
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 2
9  * of the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  *
18  */
19 
20 package org.gudy.azureus2.core3.util;
21 
22 import java.io.BufferedInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.math.BigInteger;
27 import java.security.KeyFactory;
28 import java.security.Signature;
29 import java.security.interfaces.RSAPublicKey;
30 import java.security.spec.RSAPublicKeySpec;
31 import java.util.zip.ZipEntry;
32 import java.util.zip.ZipInputStream;
33 
34 
35 public class
36 AEVerifier
37 {
38     private static final String pub_exp = "10001";
39     private static final String modulus	= "9a68296f49bf47b2a83ae4ba3cdb5a840a2689e5b36a6f2bfc27b916fc4dc9437f9087c4f0b5ae2fc5127a901b3c048753aa63d29cd7f9da7c81d475380de68236bd919230b0074aa6f40f29a78ac4a14e84fb8946cbcb5a840d1c2f77d83c795c289e37135843b8da008e082654a83b8bd3341b9f2ff6064e20b6c7ba89a707a1f3e1d8b2e0035dae539b04e49775eba23e5cbe89e22290da6c84ec3f450d07";
40 
41 	public static void
verifyData( File file )42 	verifyData(
43 		File		file )
44 
45 		throws AEVerifierException, Exception
46 	{
47 		KeyFactory key_factory = KeyFactory.getInstance("RSA");
48 
49 		RSAPublicKeySpec 	public_key_spec =
50 			new RSAPublicKeySpec( new BigInteger(modulus,16), new BigInteger(pub_exp,16));
51 
52 		RSAPublicKey public_key 	= (RSAPublicKey)key_factory.generatePublic( public_key_spec );
53 
54 		verifyData( file, public_key );
55 	}
56 
57 	protected static void
verifyData( File file, RSAPublicKey key )58 	verifyData(
59 		File			file,
60 		RSAPublicKey	key )
61 
62 		throws AEVerifierException, Exception
63 	{
64 		ZipInputStream	zis = null;
65 
66 		try{
67 			zis = new ZipInputStream(
68 					new BufferedInputStream( new FileInputStream( file ) ));
69 
70 			byte[]		signature	= null;
71 
72 			Signature	sig = Signature.getInstance("MD5withRSA" );
73 
74 			sig.initVerify( key );
75 
76 			while( true ){
77 
78 				ZipEntry	entry = zis.getNextEntry();
79 
80 				if ( entry == null ){
81 
82 					break;
83 				}
84 
85 				if ( entry.isDirectory()){
86 
87 					continue;
88 				}
89 
90 				String	name = entry.getName();
91 
92 				ByteArrayOutputStream	output = null;
93 
94 				if ( name.equalsIgnoreCase("azureus.sig")){
95 
96 					output	= new ByteArrayOutputStream();
97 				}
98 
99 				byte[]	buffer = new byte[65536];
100 
101 				while( true ){
102 
103 					int	len = zis.read( buffer );
104 
105 					if ( len <= 0 ){
106 
107 						break;
108 					}
109 
110 					if ( output == null ){
111 
112 						sig.update( buffer, 0, len );
113 
114 					}else{
115 
116 						output.write( buffer, 0, len );
117 					}
118 				}
119 
120 				if ( output != null ){
121 
122 					signature = output.toByteArray();
123 				}
124 			}
125 
126 			if ( signature == null ){
127 
128 				throw( new AEVerifierException( AEVerifierException.FT_SIGNATURE_MISSING, "Signature missing from file" ));
129 			}
130 
131 			if ( !sig.verify( signature )){
132 
133 				throw( new AEVerifierException( AEVerifierException.FT_SIGNATURE_BAD, "Signature doesn't match data" ));
134 			}
135 		}finally{
136 
137 			if ( zis != null ){
138 
139 				zis.close();
140 			}
141 		}
142 	}
143 
144 	public static void
verifyData( String data, byte[] signature )145 	verifyData(
146 		String			data,
147 		byte[]			signature )
148 
149 		throws AEVerifierException, Exception
150 	{
151 		KeyFactory key_factory = KeyFactory.getInstance("RSA");
152 
153 		RSAPublicKeySpec 	public_key_spec =
154 			new RSAPublicKeySpec( new BigInteger(modulus,16), new BigInteger(pub_exp,16));
155 
156 		RSAPublicKey public_key 	= (RSAPublicKey)key_factory.generatePublic( public_key_spec );
157 
158 		Signature	sig = Signature.getInstance("MD5withRSA" );
159 
160 		sig.initVerify( public_key );
161 
162 		sig.update( data.getBytes( "UTF-8" ));
163 
164 		if ( !sig.verify( signature )){
165 
166 			throw( new AEVerifierException( AEVerifierException.FT_SIGNATURE_BAD, "Data verification failed, signature doesn't match data" ));
167 		}
168 	}
169 }
170