chiark / gitweb /
Restrict vagrant-cachier caches to only apt and chef.
[fdroidserver.git] / tests / getsig / getsig.java
1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.math.BigInteger;
4 import java.security.Signature;
5 import java.security.cert.*;
6 import java.security.MessageDigest;
7 import java.security.NoSuchAlgorithmException;
8 import java.util.Enumeration;
9 import java.util.jar.JarEntry;
10 import java.util.jar.JarFile;
11
12 public class getsig {
13
14     public static void main(String[] args) {
15
16         String apkPath = null;
17         boolean full = false;
18
19         if(args.length == 1) {
20             apkPath = args[0];
21         } else if (args.length == 2) {
22             if(!args[0].equals("-f")) {
23                 System.out.println("Only -f is supported");
24                 System.exit(1);
25             }
26             apkPath = args[1];
27             full = true;
28         } else {
29             System.out.println("Specify the APK file to get the signature from!");
30             System.exit(1);
31         }
32
33         try {
34
35             JarFile apk = new JarFile(apkPath);
36             java.security.cert.Certificate[] certs = null;
37
38             Enumeration entries = apk.entries();
39             while (entries.hasMoreElements()) {
40                 JarEntry je = (JarEntry) entries.nextElement();
41                 if (!je.isDirectory() && !je.getName().startsWith("META-INF/")) {
42                     // Just need to read the stream (discarding the data) to get
43                     // it to process the certificate...
44                     byte[] b = new byte[4096];
45                     InputStream is = apk.getInputStream(je);
46                     while (is.read(b, 0, b.length) != -1);
47                     is.close();
48                     certs = je.getCertificates();
49                     if(certs != null)
50                         break;
51                 }
52             }
53             apk.close();
54
55             if (certs == null) {
56                 System.out.println("Not signed");
57                 System.exit(1);
58             }
59             if (certs.length != 1) {
60                 System.out.println("One signature expected");
61                 System.exit(1);
62             }
63
64             // Get the signature in the same form that is returned by
65             // android.content.pm.Signature.toCharsString() (but in the
66             // form of a byte array so we can pass it to the MD5 function)...
67             byte[] sig = certs[0].getEncoded();
68             byte[] csig = new byte[sig.length * 2];
69             for (int j=0; j<sig.length; j++) {
70                 byte v = sig[j];
71                 int d = (v>>4)&0xf;
72                 csig[j*2] = (byte)(d >= 10 ? ('a' + d - 10) : ('0' + d));
73                 d = v&0xf;
74                 csig[j*2+1] = (byte)(d >= 10 ? ('a' + d - 10) : ('0' + d));
75             }
76
77             String result;
78             if(full) {
79                 result = new String(csig);
80             } else {
81                 // Get the MD5 sum...
82                 MessageDigest md;
83                 md = MessageDigest.getInstance("MD5");
84                 byte[] md5sum = new byte[32];
85                 md.update(csig);
86                 md5sum = md.digest();
87                 BigInteger bigInt = new BigInteger(1, md5sum);
88                 String md5hash = bigInt.toString(16);
89                 while (md5hash.length() < 32)
90                     md5hash = "0" + md5hash;
91                 result = md5hash;
92             }
93
94             System.out.println("Result:" + result);
95             System.exit(0);
96
97         } catch (Exception e) {
98             System.out.println("Exception:" + e);
99             System.exit(1);
100         }
101     }
102
103 }
104
105