1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.vafer.jdeb.signing;
17
18 import java.io.BufferedReader;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.InputStreamReader;
22 import java.io.OutputStream;
23 import java.security.NoSuchAlgorithmException;
24 import java.security.NoSuchProviderException;
25 import java.security.Security;
26 import java.security.SignatureException;
27 import java.util.Iterator;
28
29 import org.bouncycastle.bcpg.ArmoredOutputStream;
30 import org.bouncycastle.bcpg.BCPGOutputStream;
31 import org.bouncycastle.jce.provider.BouncyCastleProvider;
32 import org.bouncycastle.openpgp.PGPException;
33 import org.bouncycastle.openpgp.PGPPrivateKey;
34 import org.bouncycastle.openpgp.PGPSecretKey;
35 import org.bouncycastle.openpgp.PGPSecretKeyRing;
36 import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
37 import org.bouncycastle.openpgp.PGPSignature;
38 import org.bouncycastle.openpgp.PGPSignatureGenerator;
39 import org.bouncycastle.openpgp.PGPUtil;
40
41
42
43
44
45
46
47 public final class SigningUtils {
48
49 private static PGPSecretKey getSecretKey( final InputStream pInput, final String pKey ) throws IOException, PGPException {
50
51 final PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(pInput));
52
53 final Iterator rIt = pgpSec.getKeyRings();
54
55 while (rIt.hasNext()) {
56 final PGPSecretKeyRing kRing = (PGPSecretKeyRing) rIt.next();
57 final Iterator kIt = kRing.getSecretKeys();
58
59 while (kIt.hasNext()) {
60 final PGPSecretKey k = (PGPSecretKey) kIt.next();
61
62 if (k.isSigningKey() && Long.toHexString(k.getKeyID() & 0xFFFFFFFFL).equals(pKey.toLowerCase())) {
63 return k;
64 }
65 }
66 }
67
68 return null;
69 }
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 public static void clearSign( final InputStream pInput, final InputStream pKeyring, final String pKey, final String pPassphrase, final OutputStream pOutput ) throws IOException, PGPException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException {
86
87 Security.addProvider( new BouncyCastleProvider() );
88
89 final PGPSecretKey secretKey = getSecretKey(pKeyring, pKey);
90 final PGPPrivateKey privateKey = secretKey.extractPrivateKey(pPassphrase.toCharArray(), "BC");
91
92 final int digest = PGPUtil.SHA1;
93
94 final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(secretKey.getPublicKey().getAlgorithm(), digest, "BC");
95 signatureGenerator.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, privateKey);
96
97
98
99
100
101
102
103
104
105 final ArmoredOutputStream armoredOutput = new ArmoredOutputStream(pOutput);
106
107 armoredOutput.beginClearText(digest);
108
109 final BufferedReader reader = new BufferedReader(new InputStreamReader(pInput));
110
111 final byte[] newline = "\r\n".getBytes("UTF-8");
112
113 processLine(reader.readLine(), armoredOutput, signatureGenerator);
114
115 while(true) {
116 final String line = reader.readLine();
117
118 if (line == null) {
119 armoredOutput.write(newline);
120 break;
121 }
122
123 armoredOutput.write(newline);
124 signatureGenerator.update(newline);
125
126 processLine(line, armoredOutput, signatureGenerator);
127 }
128
129 armoredOutput.endClearText();
130
131 final BCPGOutputStream pgpOutput = new BCPGOutputStream(armoredOutput);
132
133 signatureGenerator.generate().encode(pgpOutput);
134
135 armoredOutput.close();
136
137 }
138
139
140 private static void processLine( final String pLine, final ArmoredOutputStream pArmoredOutput, final PGPSignatureGenerator pSignatureGenerator ) throws IOException, SignatureException {
141
142 if (pLine == null) {
143 return;
144 }
145
146 final char[] chars = pLine.toCharArray();
147 int len = chars.length;
148
149 while(len > 0) {
150 if (!Character.isWhitespace(chars[len-1])) {
151 break;
152 }
153 len--;
154 }
155
156 final byte[] data = pLine.substring(0, len).getBytes("UTF-8");
157
158 pArmoredOutput.write(data);
159 pSignatureGenerator.update(data);
160 }
161 }