    001    /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
    002     *
    003     * Redistribution and use in  source and binary forms, with or without
    004     * modification, are permitted  provided that the following conditions are met:
    005     *
    006     * 1. Redistributions of  source code must retain the above copyright notice,
    007     *    this list of conditions and the following disclaimer.
    008     *
    009     * 2. Redistributions in  binary form must reproduce the above copyright notice,
    010     *    this list of conditions and the following disclaimer in the documentation
    011     *    and/or other materials provided with the distribution.
    012     *
    013     * 3. The end-user documentation included with the redistribution, if any, must
    014     *    include the following acknowledgment:
    015     *
    016     *    "This product includes software developed by IAIK of Graz University of
    017     *     Technology."
    018     *
    019     *    Alternately, this acknowledgment may appear in the software itself, if
    020     *    and wherever such third-party acknowledgments normally appear.
    021     *
    022     * 4. The names "Graz University of Technology" and "IAIK of Graz University of
    023     *    Technology" must not be used to endorse or promote products derived from
    024     *    this software without prior written permission.
    025     *
    026     * 5. Products derived from this software may not be called
    027     *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
    028     *    written permission of Graz University of Technology.
    029     *
    030     *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
    031     *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    032     *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    033     *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
    034     *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
    035     *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    036     *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
    037     *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    038     *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    039     *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    040     *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    041     *  POSSIBILITY  OF SUCH DAMAGE.
    042     */
    043
    044    package demo.pkcs.pkcs11;
    045
    046    import java.io.FileInputStream;
    047    import java.io.FileOutputStream;
    048    import java.io.InputStream;
    049    import java.io.OutputStream;
    050    import java.security.Security;
    051    import java.security.SignatureException;
    052
    053    import iaik.pkcs.pkcs7.SignedDataStream;
    054    import iaik.pkcs.pkcs7.SignerInfo;
    055    import iaik.security.provider.IAIK;
    056    import iaik.x509.X509Certificate;
    057
    058
    059
    060    /**
    061     * This helper class simply verifies the signature of a PKCS#7 signed data
    062     * object and extracts the verified content data.
    063     *
    064     * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
    065     * @version 0.1
    066     * @invariants
    067     */
    068    public class VerifyPKCS7SignedData {
    069
    070      public static void main(String[] args) {
    071        if ((args.length != 1) && (args.length != 2)) {
    072          printUsage();
    073          System.exit(1);
    074        }
    075
    076        try {
    077          Security.addProvider(new IAIK());
    078
    079          System.out.println("Verifying PKCS#7 signed data from file: " + args[0]);
    080          InputStream dataInput = new FileInputStream(args[0]);
    081
    082          SignedDataStream signedData = new SignedDataStream(dataInput);
    083
    084          InputStream contentStream = signedData.getInputStream();
    085          OutputStream verifiedContentStream = (args.length == 2) ? new FileOutputStream(args[1]) : null;
    086          byte[] buffer = new byte[1024];
    087          int bytesRead;
    088
    089          if (verifiedContentStream != null) {
    090            while ((bytesRead = contentStream.read(buffer)) > 0) {
    091              verifiedContentStream.write(buffer, 0, bytesRead);
    092            }
    093            verifiedContentStream.flush();
    094            verifiedContentStream.close();
    095            System.out.println("Verified content written to: " + args[1]);
    096            System.out.println("________________________________________________________________________________");
    097          } else {
    098            System.out.println("The signed content data is: ");
    099            System.out.println("________________________________________________________________________________");
    100            while ((bytesRead = contentStream.read(buffer)) > 0) {
    101              System.out.write(buffer, 0, bytesRead);
    102            }
    103            System.out.println();
    104            System.out.println("________________________________________________________________________________");
    105          }
    106
    107          // get the signer infos
    108           SignerInfo[] signerInfos = signedData.getSignerInfos();
    109           // verify the signatures
    110           for (int i=0; i < signerInfos.length; i++) {
    111             try {
    112                // verify the signature for SignerInfo at index i
    113                X509Certificate signerCertificate = signedData.verify(i);
    114                // if the signature is OK the certificate of the signer is returned
    115                System.out.println("Signature OK from signer with certificate: ");
    116                System.out.println(signerCertificate);
    117                System.out.println();
    118             } catch (SignatureException ex) {
    119                // if the signature is not OK a SignatureException is thrown
    120                System.out.println("Signature ERROR from signer with certificate: ");
    121                System.out.println(signedData.getCertificate(signerInfos[i].getIssuerAndSerialNumber()));
    122                System.out.println();
    123                ex.printStackTrace();
    124             }
    125           }
    126
    127        } catch (Throwable thr) {
    128          thr.printStackTrace();
    129        }
    130      }
    131
    132      public static void printUsage() {
    133        System.out.println("Usage: VerifyPKCS7SignedData <PKCS#7 signed data file> <verified content data>");
    134        System.out.println(" e.g.: VerifyPKCS7SignedData signedData.p7 verifiedContentData.dat");
    135      }
    136
    137
    138    }