1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.openpgp.ant;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import org.apache.commons.openpgp.BouncyCastleKeyRing;
24 import org.apache.commons.openpgp.BouncyCastleOpenPgpSignatureVerifier;
25 import org.apache.commons.openpgp.KeyRing;
26 import org.apache.commons.openpgp.OpenPgpException;
27 import org.apache.commons.openpgp.OpenPgpSignatureVerifier;
28 import org.apache.commons.openpgp.SignatureStatus;
29 import org.apache.tools.ant.BuildException;
30 import org.apache.tools.ant.Task;
31 import org.apache.tools.ant.types.Mapper;
32 import org.apache.tools.ant.util.FileNameMapper;
33 import org.apache.tools.ant.util.FileUtils;
34 import org.apache.tools.ant.util.GlobPatternMapper;
35 import org.bouncycastle.openpgp.PGPException;
36
37
38
39
40
41
42 public class OpenPgpVerifierTask extends Task {
43 private File secring;
44 private File pubring;
45 private String password;
46 private File artefact;
47 private boolean asciiarmor = true;
48 private Mapper mapperElement;
49 private String verifyproperty;
50
51
52
53
54
55 public void setSecring(File secring) {
56 this.secring = secring;
57 }
58
59
60
61
62
63 public void setPubring(File pubring) {
64 this.pubring = pubring;
65 }
66
67
68
69
70
71 public void setAsciiarmor(boolean asciiarmor) {
72 this.asciiarmor = asciiarmor;
73 }
74
75
76
77
78
79 public void setPassword(String password) {
80 this.password = password;
81 }
82
83
84
85
86
87 public void setArtefact(File artefact) {
88 this.artefact = artefact;
89 }
90
91
92
93
94
95 public void setVerifyproperty(String verifyproperty) {
96 this.verifyproperty = verifyproperty;
97 }
98
99
100
101
102
103
104 public Mapper createMapper() throws BuildException {
105 if (mapperElement != null) {
106 throw new BuildException("Cannot define more than one mapper",
107 getLocation());
108 }
109 mapperElement = new Mapper(getProject());
110 return mapperElement;
111 }
112
113 public void execute() {
114 if (secring == null) {
115 throw new BuildException("secring attribute compulsory");
116 }
117 if (pubring == null) {
118 throw new BuildException("pubring attribute compulsory");
119 }
120 if (password == null) {
121 throw new BuildException("password attribute compulsory");
122 }
123 if (artefact == null) {
124 throw new BuildException("The 'artefact' attribute is compulsory.");
125 }
126 if (verifyproperty == null) {
127 throw new BuildException("The 'verifyproperty' attribute is compulsory.");
128 }
129 if (!secring.exists() || !secring.canRead()) {
130 throw new BuildException("secret keyring file '" + secring.getAbsolutePath() + "' does not exist or is not readable");
131 }
132 if (!pubring.exists() || !pubring.canRead()) {
133 throw new BuildException("public keyring file '" + pubring.getAbsolutePath() + "' does not exist or is not readable");
134 }
135 FileInputStream secStream;
136 FileInputStream pubStream;
137 KeyRing keyRing = null;
138 try {
139 secStream = new FileInputStream(secring);
140 pubStream = new FileInputStream(pubring);
141 keyRing = new BouncyCastleKeyRing(secStream,
142 pubStream, password.toCharArray() );
143 } catch (IOException ioe) {
144 throw new BuildException(ioe);
145 } catch (PGPException pgpe) {
146 throw new BuildException(pgpe);
147 }
148 if (artefact != null) {
149 doHandle(keyRing, artefact);
150 }
151 FileUtils.close(secStream);
152 FileUtils.close(pubStream);
153 }
154
155 private void doHandle(KeyRing keyRing, File oneartefact) {
156 doHandle(keyRing, oneartefact, oneartefact.getParentFile(), oneartefact.getName());
157 }
158
159 private void doHandle(KeyRing keyRing, File oneartefact, File basedir, String relpath) {
160 FileInputStream artifactFis = null;
161 FileInputStream signatureFis = null;
162 File signature;
163 boolean isValid = false;
164
165 try {
166 artifactFis = new FileInputStream(oneartefact);
167 FileNameMapper mapper = getMapper();
168 String [] mappedFiles = mapper.mapFileName(relpath);
169 if (mappedFiles == null || mappedFiles.length != 1) {
170 throw new BuildException("mapper returned more or less than one output");
171 }
172 signature = new File(basedir, mappedFiles[0]);
173 signatureFis = new FileInputStream(signature);
174 OpenPgpSignatureVerifier verifier = new BouncyCastleOpenPgpSignatureVerifier();
175 SignatureStatus status = verifier.verifyDetachedSignature(artifactFis, signatureFis, keyRing);
176 isValid = status.isValid();
177 } catch (FileNotFoundException fnfe) {
178 throw new BuildException(fnfe);
179 } catch (IOException ioe) {
180 throw new BuildException(ioe);
181 } catch (OpenPgpException opgpe) {
182 throw new BuildException(opgpe);
183 }
184 finally {
185 getProject().setProperty(verifyproperty, Boolean.toString(isValid));
186 }
187 FileUtils.close(signatureFis);
188 FileUtils.close(artifactFis);
189 }
190
191
192
193
194 private FileNameMapper getMapper() {
195 FileNameMapper mapper = null;
196 if (mapperElement != null) {
197 mapper = mapperElement.getImplementation();
198 } else {
199 mapper = new GlobPatternMapper();
200 mapper.setFrom("*");
201 if (asciiarmor) {
202 mapper.setTo("*.asc");
203 } else {
204 mapper.setTo("*.sig");
205 }
206 }
207 return mapper;
208 }
209 }