Author: dennisl
Date: Sat Apr 17 14:29:14 2010
New Revision: 935179
URL: http://svn.apache.org/viewvc?rev=935179&view=rev
Log:
[SANDBOX-321] Ant task to verify a signature
Added:
commons/sandbox/openpgp/trunk/src/main/java/org/apache/commons/openpgp/ant/OpenPgpVerifierTask.java
(with props)
commons/sandbox/openpgp/trunk/src/site/apt/verifier.apt (with props)
Modified:
commons/sandbox/openpgp/trunk/src/main/resources/org/apache/commons/openpgp/ant/antlib.xml
commons/sandbox/openpgp/trunk/src/site/site.xml
Added:
commons/sandbox/openpgp/trunk/src/main/java/org/apache/commons/openpgp/ant/OpenPgpVerifierTask.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/openpgp/trunk/src/main/java/org/apache/commons/openpgp/ant/OpenPgpVerifierTask.java?rev=935179&view=auto
==============================================================================
---
commons/sandbox/openpgp/trunk/src/main/java/org/apache/commons/openpgp/ant/OpenPgpVerifierTask.java
(added)
+++
commons/sandbox/openpgp/trunk/src/main/java/org/apache/commons/openpgp/ant/OpenPgpVerifierTask.java
Sat Apr 17 14:29:14 2010
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.openpgp.ant;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import org.apache.commons.openpgp.BouncyCastleKeyRing;
+import org.apache.commons.openpgp.BouncyCastleOpenPgpSignatureVerifier;
+import org.apache.commons.openpgp.KeyRing;
+import org.apache.commons.openpgp.OpenPgpException;
+import org.apache.commons.openpgp.OpenPgpSignatureVerifier;
+import org.apache.commons.openpgp.SignatureStatus;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.GlobPatternMapper;
+import org.bouncycastle.openpgp.PGPException;
+
+/**
+ * Verify a signature using the Bouncy Castle OpenPGP provider.
+ *
+ * @author <a href="mailto:[email protected]">Dennis Lundberg</a>
+ */
+public class OpenPgpVerifierTask extends Task {
+ private File secring;
+ private File pubring;
+ private String password;
+ private File artefact;
+ private boolean asciiarmor = true;
+ private Mapper mapperElement;
+ private String verifyproperty;
+
+ /**
+ * Set the secret keyring.
+ * @param secring secret keyring file
+ */
+ public void setSecring(File secring) {
+ this.secring = secring;
+ }
+
+ /**
+ * Set the public keyring.
+ * @param pubring public keyring file
+ */
+ public void setPubring(File pubring) {
+ this.pubring = pubring;
+ }
+
+ /**
+ * Use ASCII armored signature files?
+ * @param asciiarmor ascii armored signatures?
+ */
+ public void setAsciiarmor(boolean asciiarmor) {
+ this.asciiarmor = asciiarmor;
+ }
+
+ /**
+ * Set the value of the password.
+ * @param password value of the password
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Set the artefact to be handled.
+ * @param artefact artefact to be handled
+ */
+ public void setArtefact(File artefact) {
+ this.artefact = artefact;
+ }
+
+ /**
+ * Set the name of the property that contains the result of the
verification.
+ * @param verifyproperty name of the property
+ */
+ public void setVerifyproperty(String verifyproperty) {
+ this.verifyproperty = verifyproperty;
+ }
+
+ /**
+ * Define the mapper to map source to destination files.
+ * @return a mapper to be configured.
+ * @exception org.apache.tools.ant.BuildException if more than one mapper
is defined.
+ */
+ public Mapper createMapper() throws BuildException {
+ if (mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper",
+ getLocation());
+ }
+ mapperElement = new Mapper(getProject());
+ return mapperElement;
+ }
+
+ public void execute() {
+ if (secring == null) {
+ throw new BuildException("secring attribute compulsory");
+ }
+ if (pubring == null) {
+ throw new BuildException("pubring attribute compulsory");
+ }
+ if (password == null) {
+ throw new BuildException("password attribute compulsory");
+ }
+ if (artefact == null) {
+ throw new BuildException("The 'artefact' attribute is
compulsory.");
+ }
+ if (verifyproperty == null) {
+ throw new BuildException("The 'verifyproperty' attribute is
compulsory.");
+ }
+ if (!secring.exists() || !secring.canRead()) {
+ throw new BuildException("secret keyring file '" +
secring.getAbsolutePath() + "' does not exist or is not readable");
+ }
+ if (!pubring.exists() || !pubring.canRead()) {
+ throw new BuildException("public keyring file '" +
pubring.getAbsolutePath() + "' does not exist or is not readable");
+ }
+ FileInputStream secStream;
+ FileInputStream pubStream;
+ KeyRing keyRing = null;
+ try {
+ secStream = new FileInputStream(secring);
+ pubStream = new FileInputStream(pubring);
+ keyRing = new BouncyCastleKeyRing(secStream,
+ pubStream, password.toCharArray() );
+ } catch (IOException ioe) {
+ throw new BuildException(ioe);
+ } catch (PGPException pgpe) {
+ throw new BuildException(pgpe);
+ }
+ if (artefact != null) {
+ doHandle(keyRing, artefact);
+ }
+ FileUtils.close(secStream);
+ FileUtils.close(pubStream);
+ }
+
+ private void doHandle(KeyRing keyRing, File oneartefact) {
+ doHandle(keyRing, oneartefact, oneartefact.getParentFile(),
oneartefact.getName());
+ }
+
+ private void doHandle(KeyRing keyRing, File oneartefact, File basedir,
String relpath) {
+ FileInputStream artifactFis = null;
+ FileInputStream signatureFis = null;
+ File signature;
+ boolean isValid = false;
+
+ try {
+ artifactFis = new FileInputStream(oneartefact);
+ FileNameMapper mapper = getMapper();
+ String [] mappedFiles = mapper.mapFileName(relpath);
+ if (mappedFiles == null || mappedFiles.length != 1) {
+ throw new BuildException("mapper returned more or less than
one output");
+ }
+ signature = new File(basedir, mappedFiles[0]);
+ signatureFis = new FileInputStream(signature);
+ OpenPgpSignatureVerifier verifier = new
BouncyCastleOpenPgpSignatureVerifier();
+ SignatureStatus status =
verifier.verifyDetachedSignature(artifactFis, signatureFis, keyRing);
+ isValid = status.isValid();
+ } catch (FileNotFoundException fnfe) {
+ throw new BuildException(fnfe);
+ } catch (IOException ioe) {
+ throw new BuildException(ioe);
+ } catch (OpenPgpException opgpe) {
+ throw new BuildException(opgpe);
+ }
+ finally {
+ getProject().setProperty(verifyproperty,
Boolean.toString(isValid));
+ }
+ FileUtils.close(signatureFis);
+ FileUtils.close(artifactFis);
+ }
+
+ /**
+ * Return the mapper to use based on nested elements or use a default
mapping.
+ */
+ private FileNameMapper getMapper() {
+ FileNameMapper mapper = null;
+ if (mapperElement != null) {
+ mapper = mapperElement.getImplementation();
+ } else {
+ mapper = new GlobPatternMapper();
+ mapper.setFrom("*");
+ if (asciiarmor) {
+ mapper.setTo("*.asc");
+ } else {
+ mapper.setTo("*.sig");
+ }
+ }
+ return mapper;
+ }
+}
Propchange:
commons/sandbox/openpgp/trunk/src/main/java/org/apache/commons/openpgp/ant/OpenPgpVerifierTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
commons/sandbox/openpgp/trunk/src/main/java/org/apache/commons/openpgp/ant/OpenPgpVerifierTask.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author Id
Modified:
commons/sandbox/openpgp/trunk/src/main/resources/org/apache/commons/openpgp/ant/antlib.xml
URL:
http://svn.apache.org/viewvc/commons/sandbox/openpgp/trunk/src/main/resources/org/apache/commons/openpgp/ant/antlib.xml?rev=935179&r1=935178&r2=935179&view=diff
==============================================================================
---
commons/sandbox/openpgp/trunk/src/main/resources/org/apache/commons/openpgp/ant/antlib.xml
(original)
+++
commons/sandbox/openpgp/trunk/src/main/resources/org/apache/commons/openpgp/ant/antlib.xml
Sat Apr 17 14:29:14 2010
@@ -3,4 +3,7 @@
<taskdef name="signer"
classname="org.apache.commons.openpgp.ant.OpenPgpSignerTask"
/>
+ <taskdef name="verifier"
+ classname="org.apache.commons.openpgp.ant.OpenPgpVerifierTask"
+ />
</antlib>
\ No newline at end of file
Added: commons/sandbox/openpgp/trunk/src/site/apt/verifier.apt
URL:
http://svn.apache.org/viewvc/commons/sandbox/openpgp/trunk/src/site/apt/verifier.apt?rev=935179&view=auto
==============================================================================
--- commons/sandbox/openpgp/trunk/src/site/apt/verifier.apt (added)
+++ commons/sandbox/openpgp/trunk/src/site/apt/verifier.apt Sat Apr 17 14:29:14
2010
@@ -0,0 +1,57 @@
+ -----
+ Verifier Ant Task
+ -----
+ Dennis Lundberg
+ -----
+ 2010-04-17
+ -----
+
+Verifier Ant Task
+
+ This task is packaged in <<<commons-openpgp.jar>>>.
+ It will use the BouncyCastle JARs at runtime. It has been tested with
<<<bcpg-jdk12-134.jar>>> and <<<bcprov-jdk12-134.jar>>>.
+
+ The <<<verifier>>> task can verify one file at a time.
+
+* Attributes
+
+*----------------------+--------------------------------------------------------------------------+-------------------------------------------------+
+|| Attribute || Description
|| Required |
+*----------------------+--------------------------------------------------------------------------+-------------------------------------------------+
+| <<<secring>>> | Secret key ring file.
| Yes |
+*----------------------+--------------------------------------------------------------------------+-------------------------------------------------+
+| <<<pubring>>> | Public key ring file.
| Yes |
+*----------------------+--------------------------------------------------------------------------+-------------------------------------------------+
+| <<<password>>> | Password of the secret key ring.
| Yes |
+*----------------------+--------------------------------------------------------------------------+-------------------------------------------------+
+| <<<asciiarmor>>> | Whether the signature is ASCII armored. Boolean,
defaults to <<<true>>>. | No |
+*----------------------+--------------------------------------------------------------------------+-------------------------------------------------+
+| <<<artefact>>> | The file that you want to verify.
| Yes |
+*----------------------+--------------------------------------------------------------------------+-------------------------------------------------+
+| <<<verifyproperty>>> | The name of the property that will hold the result of
the verification. | Yes |
+*----------------------+--------------------------------------------------------------------------+-------------------------------------------------+
+
+** <<<mapper>>> nested element
+
+ The task may take a {{{http://ant.apache.org/manual/CoreTypes/mapper.html}
mapper}} nested element.
+ This nested element tells the task how the signature files should be named.
+ If you do not supply this element, the signature files should be located in
the same directory as the file that
+ you verify. An ending of <<<.asc>>> will be used for the file name for ASCII
armored input (the default).
+ If you set <<<asciiarmor>>> to false, the ending will be <<<.sig>>>
+
+
+* Example
+
+-----
+<project name="test1" xmlns:openpgp="antlib:org.apache.commons.openpgp.ant">
+ <property environment="env"/>
+ <taskdef resource="org/apache/commons/openpgp/ant/antlib.xml"
uri="antlib:org.apache.commons.openpgp.ant"/>
+ <openpgp:verifier secring="${env.USERPROFILE}\Application
Data\gnupg\secring.gpg"
+ pubring="${env.USERPROFILE}\Application Data\gnupg\pubring.gpg"
+ password="secret"
+ artefact="target\commons-openpgp-1.0-SNAPSHOT.jar"
+ asciiarmor="true"
+ verifyproperty="isValidSignature"/>
+ <echo message="The signature is valid: ${isValidSignature}"/>
+</project>
+-----
Propchange: commons/sandbox/openpgp/trunk/src/site/apt/verifier.apt
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/sandbox/openpgp/trunk/src/site/apt/verifier.apt
------------------------------------------------------------------------------
svn:keywords = Date Revision Author Id
Modified: commons/sandbox/openpgp/trunk/src/site/site.xml
URL:
http://svn.apache.org/viewvc/commons/sandbox/openpgp/trunk/src/site/site.xml?rev=935179&r1=935178&r2=935179&view=diff
==============================================================================
--- commons/sandbox/openpgp/trunk/src/site/site.xml (original)
+++ commons/sandbox/openpgp/trunk/src/site/site.xml Sat Apr 17 14:29:14 2010
@@ -11,7 +11,11 @@
<menu name="Commons OpenPGP">
<item name="Overview" href="/index.html" />
<item name="Usage" href="/usage.html" />
- <item name="Signer Ant Task" href="/signer.html"/>
+ </menu>
+
+ <menu name="Ant Tasks">
+ <item name="Signer" href="/signer.html"/>
+ <item name="Verifier" href="/verifier.html"/>
</menu>
<menu name="Development">