senzacionale
senzacionale

Reputation: 20916

How can I check a signed jar file using Ant?

I sign jar files with the Ant signjar task and now I want to test before deploy.

I can check with

jarsigner -verify sbundle.jar 

but I do not know if it is possible to do the same with Ant?

Upvotes: 6

Views: 4010

Answers (5)

Suman Mummaneni
Suman Mummaneni

Reputation: 53

You can use the VerifyJar Task in Ant to do this. Here is the link to Ant help https://ant.apache.org/manual/Tasks/verifyjar.html

Sample code for Verifying multiple JAR files at once.

<verifyjar keystore="mykeystore" keypass="abc"
          storepass="abc" alias="myalias">
    <path>
        <fileset dir="${build.dir}/signedjar" includes="**/*.jar" />
    </path>
</verifyjar>

Upvotes: 2

Vadzim
Vadzim

Reputation: 26200

Based on @torkildr's answer.

It's possible to make macro pass nested path or fileset to ant-contrib for task.

<target name="verify-artifacts" description="Just an example of usage">
    <verify-artifacts>
        <fileset dir="${project.ear.dir}" includes="*.*ar"/>
    </verify-artifacts>
</target>

<macrodef name="verify-artifacts">
    <element name="artifact-path" implicit="true"/>
    <sequential>
        <for param="file">
            <artifact-path/>
            <sequential>
                <verify-artifact file="@{file}"/>
            </sequential>
        </for>
    </sequential>
</macrodef>

<macrodef name="verify-artifact">
    <attribute name="file"/>
    <attribute name="alias" default="${artifact.sign.keystore.alias}"/>
    <attribute name="keystore" default="${artifact.sign.keystore.path}"/>
    <attribute name="password" default="${artifact.sign.keystore.password}"/>
    <sequential>
        <if>
            <istrue value="${artifact.sign.enabled}"/>
            <then>
                <echo message="Trying to verify @{file} with alias @{alias} from @{keystore}"/>
                <required-macro-param value="@{alias}" prop="artifact.sign.keystore.alias"/>
                <required-macro-param value="@{keystore}" prop="artifact.sign.keystore.path"/>
                <required-macro-param value="@{password}" prop="artifact.sign.keystore.password"/>
                <fail message="Keystore path '@{keystore}' not found">
                    <condition>
                        <not><available file="@{keystore}" type="file"/></not>
                    </condition>
                </fail>
                <fail message="Artifact '@{file}' not found">
                    <condition>
                        <not><available file="@{file}" type="file"/></not>
                    </condition>
                </fail>
                <!-- jarsigner -verify -keystore @{keystore} -storepass @{password} @{file} @{alias} -->
                <exec executable="jarsigner" failonerror="true">
                    <arg value="-verify"/>
                    <arg value="-keystore"/>
                    <arg value="@{keystore}"/>
                    <arg value="-storepass"/>
                    <arg value="@{password}"/>
                    <arg value="@{file}"/>
                    <arg value="@{alias}"/>
                </exec>
            </then>
        </if>
    </sequential>
</macrodef>

<macrodef name="required-macro-param">
    <attribute name="prop"/>
    <attribute name="value"/>
    <sequential>
        <!--<echo message="@{value}"/>-->
        <fail message="You must set property '@{prop}'">
            <condition>
                <and>
                    <or>
                        <equals arg1="@{value}" arg2=""/>
                        <matches string="@{value}" pattern="^\$\{.*?\}$"/>
                    </or>
                    <!--<not><isset property="@{prop}"/></not>-->
                </and>
            </condition>
        </fail>
    </sequential>
</macrodef>

<macrodef name="sign-artifact">
    <attribute name="file"/>
    <attribute name="alias" default="${artifact.sign.keystore.alias}"/>
    <attribute name="keystore" default="${artifact.sign.keystore.path}"/>
    <attribute name="password" default="${artifact.sign.keystore.password}"/>
    <sequential>
        <if>
            <istrue value="${artifact.sign.enabled}"/>
            <then>
                <echo message="Trying to sign @{file} with alias @{alias} from @{keystore}"/>
                <required-macro-param value="@{alias}" prop="artifact.sign.keystore.alias"/>
                <required-macro-param value="@{keystore}" prop="artifact.sign.keystore.path"/>
                <required-macro-param value="@{password}" prop="artifact.sign.keystore.password"/>
                <fail message="Keystore path '@{keystore}' not found">
                    <condition>
                        <not><available file="@{keystore}" type="file"/></not>
                    </condition>
                </fail>
                <fail message="Artifact '@{file}' not found">
                    <condition>
                        <not><available file="@{file}" type="file"/></not>
                    </condition>
                </fail>
                <signjar jar="@{file}" alias="@{alias}" keystore="@{keystore}" storepass="@{password}"/>
                <fail message="Signature check failed">
                    <condition>
                        <not><issigned file="@{file}" name="@{alias}"/></not>
                    </condition>
                </fail>
            </then>
        </if>
    </sequential>
</macrodef>

<macrodef name="sign-artifacts">
    <element name="artifact-path" implicit="true"/>
    <sequential>
        <for param="file">
            <artifact-path/>
            <sequential>
                <sign-artifact file="@{file}"/>
            </sequential>
        </for>
    </sequential>
</macrodef>

<property name="artifact.sign.enabled" value="true"/>
<property name="artifact.sign.keystore.alias" value="alias"/>
<property name="artifact.sign.keystore.path" value="keystore.jks"/>
<property name="artifact.sign.keystore.password" value="pwd"/>

Upvotes: 1

torkildr
torkildr

Reputation: 335

The following Ant code can be used for verifying JAR-file signatures. The script will fail as soon as it encounters a JAR-file where the signature is not valid or where it is missing.

Note that ant-contrib is required for the for task.

<!-- Macro to verify whether or not a JAR file is signed -->
<macrodef name="verify-signatures">
    <attribute name="filesetref" />
    <sequential>
        <for param="file">
            <path>
                <fileset refid="@{filesetref}" />
            </path>
            <sequential>
                <echo message="Verifying signature on file: @{file}" />
                <exec executable="jarsigner" failonerror="true">
                    <arg value="-verify" />
                    <arg value="@{file}" />
                </exec>
                <fail message="@{file} must be signed">
                    <condition>
                        <not>
                            <issigned file="@{file}" />
                        </not>
                    </condition>
                </fail>
            </sequential>
        </for>
    </sequential>
</macrodef>

<!-- Define the list of files to check -->
<fileset dir="p2repo" id="jarfiles">
    <include name="**/*.jar" />
</fileset>

<!-- Verify signatures -->   
<verify-signatures filesetref="jarfiles" />

Upvotes: 4

Abhijeet Kashnia
Abhijeet Kashnia

Reputation: 12900

Ant conditions offer "issigned".

"Test whether a jarfile is signed. If the name of the signature is passed, the file is checked for presence of that particular signature; otherwise the file is checked for the existence of any signature. It does not perform rigorous signature validation; it only looks for the presence of a signature. This condition was added in Apache Ant 1.7."

From Ant conditions

Upvotes: 3

VonC
VonC

Reputation: 1326706

An alternative would be to base your build on a maven script.
Maven does propose the jarsigner:verify plugin

If that is not a valid possibility, you still can use the Exec Ant task to directly call the jarsigner command. If the return code is correctly set, you can add the attribute failonerror (Stop the build process if the command exits with a return code other than 0.)

Upvotes: 5

Related Questions