151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.security.pkcs;
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.math.BigInteger;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.X509Certificate;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.CertificateException;
34e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubinimport java.security.cert.CertificateEncodingException;
35e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubinimport java.security.cert.CertificateExpiredException;
36e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubinimport java.security.cert.CertificateNotYetValidException;
37e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubinimport java.security.cert.CertificateParsingException;
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.X509CRL;
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.CRLException;
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.CertificateFactory;
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.*;
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
43e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubinimport javax.security.auth.x500.X500Principal;
44e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.*;
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.x509.AlgorithmId;
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.x509.CertificateIssuerName;
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.x509.X509CertImpl;
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.x509.X509CertInfo;
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.x509.X509CRLImpl;
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.x509.X500Name;
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * PKCS7 as defined in RSA Laboratories PKCS7 Technical Note. Profile
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Supports only <tt>SignedData</tt> ContentInfo
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * type, where to the type of data signed is plain Data.
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For signedData, <tt>crls</tt>, <tt>attributes</tt> and
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * PKCS#6 Extended Certificates are not supported.
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Benjamin Renaud
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class PKCS7 {
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private ObjectIdentifier contentType;
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // the ASN.1 members for a signedData (and other) contentTypes
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private BigInteger version = null;
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private AlgorithmId[] digestAlgorithmIds = null;
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private ContentInfo contentInfo = null;
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private X509Certificate[] certificates = null;
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private X509CRL[] crls = null;
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private SignerInfo[] signerInfos = null;
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean oldStyle = false; // Is this JDK1.1.x-style?
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Principal[] certIssuerNames;
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Unmarshals a PKCS7 block from its encoded form, parsing the
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * encoded bytes from the InputStream.
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param in an input stream holding at least one PKCS7 block.
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception ParsingException on parsing errors.
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException on other errors.
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public PKCS7(InputStream in) throws ParsingException, IOException {
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DataInputStream dis = new DataInputStream(in);
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        byte[] data = new byte[dis.available()];
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        dis.readFully(data);
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        parse(new DerInputStream(data));
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Unmarshals a PKCS7 block from its encoded form, parsing the
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * encoded bytes from the DerInputStream.
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param derin a DerInputStream holding at least one PKCS7 block.
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception ParsingException on parsing errors.
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public PKCS7(DerInputStream derin) throws ParsingException {
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        parse(derin);
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Unmarshals a PKCS7 block from its encoded form, parsing the
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * encoded bytes.
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param bytes the encoded bytes.
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception ParsingException on parsing errors.
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public PKCS7(byte[] bytes) throws ParsingException {
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            DerInputStream derin = new DerInputStream(bytes);
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            parse(derin);
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException ioe1) {
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ParsingException pe = new ParsingException(
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                "Unable to parse the encoded bytes");
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            pe.initCause(ioe1);
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw pe;
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Parses a PKCS#7 block.
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void parse(DerInputStream derin)
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws ParsingException
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            derin.mark(derin.available());
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // try new (i.e., JDK1.2) style
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            parse(derin, false);
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException ioe) {
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                derin.reset();
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // try old (i.e., JDK1.1.x) style
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                parse(derin, true);
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                oldStyle = true;
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (IOException ioe1) {
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ParsingException pe = new ParsingException(
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ioe1.getMessage());
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                pe.initCause(ioe);
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                pe.addSuppressed(ioe1);
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw pe;
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Parses a PKCS#7 block.
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param derin the ASN.1 encoding of the PKCS#7 block.
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param oldStyle flag indicating whether or not the given PKCS#7 block
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is encoded according to JDK1.1.x.
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void parse(DerInputStream derin, boolean oldStyle)
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        contentInfo = new ContentInfo(derin, oldStyle);
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        contentType = contentInfo.contentType;
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerValue content = contentInfo.getContent();
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (contentType.equals(ContentInfo.SIGNED_DATA_OID)) {
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            parseSignedData(content);
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else if (contentType.equals(ContentInfo.OLD_SIGNED_DATA_OID)) {
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // This is for backwards compatibility with JDK 1.1.x
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            parseOldSignedData(content);
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else if (contentType.equals(ContentInfo.NETSCAPE_CERT_SEQUENCE_OID)){
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            parseNetscapeCertChain(content);
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new ParsingException("content type " + contentType +
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                       " not supported.");
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Construct an initialized PKCS7 block.
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param digestAlgorithmIds the message digest algorithm identifiers.
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param contentInfo the content information.
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param certificates an array of X.509 certificates.
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param crls an array of CRLs
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param signerInfos an array of signer information.
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public PKCS7(AlgorithmId[] digestAlgorithmIds,
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 ContentInfo contentInfo,
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 X509Certificate[] certificates,
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 X509CRL[] crls,
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 SignerInfo[] signerInfos) {
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        version = BigInteger.ONE;
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.digestAlgorithmIds = digestAlgorithmIds;
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.contentInfo = contentInfo;
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.certificates = certificates;
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.crls = crls;
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.signerInfos = signerInfos;
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public PKCS7(AlgorithmId[] digestAlgorithmIds,
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 ContentInfo contentInfo,
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 X509Certificate[] certificates,
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 SignerInfo[] signerInfos) {
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(digestAlgorithmIds, contentInfo, certificates, null, signerInfos);
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void parseNetscapeCertChain(DerValue val)
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    throws ParsingException, IOException {
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerInputStream dis = new DerInputStream(val.toByteArray());
21011dda1f70e04ac28129dbccbd3037169094da68cAlex Klyubin        DerValue[] contents = dis.getSequence(2, true);
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        certificates = new X509Certificate[contents.length];
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        CertificateFactory certfac = null;
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            certfac = CertificateFactory.getInstance("X.509");
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (CertificateException ce) {
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // do nothing
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i=0; i < contents.length; i++) {
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ByteArrayInputStream bais = null;
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
223e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                byte[] original = contents[i].getOriginalEncodedForm();
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (certfac == null)
225e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                    certificates[i] = new X509CertImpl(contents[i], original);
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else {
227e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                    bais = new ByteArrayInputStream(original);
228e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                    certificates[i] = new VerbatimX509Certificate(
229e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                        (X509Certificate)certfac.generateCertificate(bais),
230e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                        original);
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    bais.close();
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    bais = null;
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (CertificateException ce) {
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ParsingException pe = new ParsingException(ce.getMessage());
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                pe.initCause(ce);
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw pe;
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (IOException ioe) {
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ParsingException pe = new ParsingException(ioe.getMessage());
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                pe.initCause(ioe);
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw pe;
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } finally {
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (bais != null)
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    bais.close();
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void parseSignedData(DerValue val)
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws ParsingException, IOException {
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerInputStream dis = val.toDerInputStream();
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Version
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        version = dis.getBigInteger();
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // digestAlgorithmIds
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerValue[] digestAlgorithmIdVals = dis.getSet(1);
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int len = digestAlgorithmIdVals.length;
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        digestAlgorithmIds = new AlgorithmId[len];
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < len; i++) {
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                DerValue oid = digestAlgorithmIdVals[i];
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digestAlgorithmIds[i] = AlgorithmId.parse(oid);
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException e) {
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ParsingException pe =
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                new ParsingException("Error parsing digest AlgorithmId IDs: " +
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                     e.getMessage());
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            pe.initCause(e);
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw pe;
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // contentInfo
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        contentInfo = new ContentInfo(dis);
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        CertificateFactory certfac = null;
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            certfac = CertificateFactory.getInstance("X.509");
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (CertificateException ce) {
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // do nothing
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * check if certificates (implicit tag) are provided
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * (certificates are OPTIONAL)
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((byte)(dis.peekByte()) == (byte)0xA0) {
289e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            DerValue[] certVals = dis.getSet(2, true, true);
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            len = certVals.length;
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            certificates = new X509Certificate[len];
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int count = 0;
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < len; i++) {
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ByteArrayInputStream bais = null;
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    byte tag = certVals[i].getTag();
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // We only parse the normal certificate. Other types of
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // CertificateChoices ignored.
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (tag == DerValue.tag_Sequence) {
302e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                        byte[] original = certVals[i].getOriginalEncodedForm();
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (certfac == null) {
304e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                            certificates[count] = new X509CertImpl(certVals[i], original);
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } else {
306e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                            bais = new ByteArrayInputStream(original);
307e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                            certificates[count] = new VerbatimX509Certificate(
308e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                                (X509Certificate)certfac.generateCertificate(bais),
309e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                                original);
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            bais.close();
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            bais = null;
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        count++;
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (CertificateException ce) {
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ParsingException pe = new ParsingException(ce.getMessage());
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    pe.initCause(ce);
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw pe;
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (IOException ioe) {
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ParsingException pe = new ParsingException(ioe.getMessage());
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    pe.initCause(ioe);
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw pe;
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } finally {
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (bais != null)
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        bais.close();
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (count != len) {
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                certificates = Arrays.copyOf(certificates, count);
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // check if crls (implicit tag) are provided (crls are OPTIONAL)
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((byte)(dis.peekByte()) == (byte)0xA1) {
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            DerValue[] crlVals = dis.getSet(1, true);
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            len = crlVals.length;
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            crls = new X509CRL[len];
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < len; i++) {
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ByteArrayInputStream bais = null;
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (certfac == null)
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        crls[i] = new X509CRLImpl(crlVals[i]);
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    else {
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        byte[] encoded = crlVals[i].toByteArray();
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        bais = new ByteArrayInputStream(encoded);
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        crls[i] = (X509CRL) certfac.generateCRL(bais);
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        bais.close();
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        bais = null;
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (CRLException e) {
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ParsingException pe =
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        new ParsingException(e.getMessage());
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    pe.initCause(e);
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw pe;
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } finally {
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (bais != null)
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        bais.close();
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // signerInfos
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerValue[] signerInfoVals = dis.getSet(1);
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        len = signerInfoVals.length;
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        signerInfos = new SignerInfo[len];
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < len; i++) {
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            DerInputStream in = signerInfoVals[i].toDerInputStream();
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            signerInfos[i] = new SignerInfo(in);
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Parses an old-style SignedData encoding (for backwards
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * compatibility with JDK1.1.x).
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void parseOldSignedData(DerValue val)
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws ParsingException, IOException
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerInputStream dis = val.toDerInputStream();
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Version
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        version = dis.getBigInteger();
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // digestAlgorithmIds
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerValue[] digestAlgorithmIdVals = dis.getSet(1);
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int len = digestAlgorithmIdVals.length;
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        digestAlgorithmIds = new AlgorithmId[len];
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < len; i++) {
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                DerValue oid = digestAlgorithmIdVals[i];
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digestAlgorithmIds[i] = AlgorithmId.parse(oid);
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException e) {
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new ParsingException("Error parsing digest AlgorithmId IDs");
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // contentInfo
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        contentInfo = new ContentInfo(dis, true);
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // certificates
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        CertificateFactory certfac = null;
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            certfac = CertificateFactory.getInstance("X.509");
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (CertificateException ce) {
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // do nothing
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
41211dda1f70e04ac28129dbccbd3037169094da68cAlex Klyubin        DerValue[] certVals = dis.getSet(2, false, true);
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        len = certVals.length;
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        certificates = new X509Certificate[len];
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < len; i++) {
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ByteArrayInputStream bais = null;
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
419e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                byte[] original = certVals[i].getOriginalEncodedForm();
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (certfac == null)
421e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                    certificates[i] = new X509CertImpl(certVals[i], original);
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else {
423e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                    bais = new ByteArrayInputStream(original);
424e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                    certificates[i] = new VerbatimX509Certificate(
425e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                        (X509Certificate)certfac.generateCertificate(bais),
426e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                        original);
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    bais.close();
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    bais = null;
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (CertificateException ce) {
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ParsingException pe = new ParsingException(ce.getMessage());
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                pe.initCause(ce);
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw pe;
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (IOException ioe) {
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ParsingException pe = new ParsingException(ioe.getMessage());
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                pe.initCause(ioe);
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw pe;
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } finally {
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (bais != null)
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    bais.close();
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // crls are ignored.
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        dis.getSet(0);
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // signerInfos
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerValue[] signerInfoVals = dis.getSet(1);
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        len = signerInfoVals.length;
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        signerInfos = new SignerInfo[len];
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < len; i++) {
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            DerInputStream in = signerInfoVals[i].toDerInputStream();
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            signerInfos[i] = new SignerInfo(in, true);
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Encodes the signed data to an output stream.
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param out the output stream to write the encoded data to.
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException on encoding errors.
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void encodeSignedData(OutputStream out) throws IOException {
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerOutputStream derout = new DerOutputStream();
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        encodeSignedData(derout);
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        out.write(derout.toByteArray());
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Encodes the signed data to a DerOutputStream.
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param out the DerOutputStream to write the encoded data to.
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException on encoding errors.
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void encodeSignedData(DerOutputStream out)
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerOutputStream signedData = new DerOutputStream();
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // version
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        signedData.putInteger(version);
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // digestAlgorithmIds
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        signedData.putOrderedSetOf(DerValue.tag_Set, digestAlgorithmIds);
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // contentInfo
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        contentInfo.encode(signedData);
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // certificates (optional)
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (certificates != null && certificates.length != 0) {
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // cast to X509CertImpl[] since X509CertImpl implements DerEncoder
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            X509CertImpl implCerts[] = new X509CertImpl[certificates.length];
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < certificates.length; i++) {
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (certificates[i] instanceof X509CertImpl)
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    implCerts[i] = (X509CertImpl) certificates[i];
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else {
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    try {
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        byte[] encoded = certificates[i].getEncoded();
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        implCerts[i] = new X509CertImpl(encoded);
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } catch (CertificateException ce) {
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        IOException ie = new IOException(ce.getMessage());
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ie.initCause(ce);
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw ie;
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Add the certificate set (tagged with [0] IMPLICIT)
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // to the signed data
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            signedData.putOrderedSetOf((byte)0xA0, implCerts);
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // CRLs (optional)
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (crls != null && crls.length != 0) {
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Set<X509CRLImpl> implCRLs = new HashSet<X509CRLImpl>(crls.length);
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (X509CRL crl: crls) {
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (crl instanceof X509CRLImpl)
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    implCRLs.add((X509CRLImpl) crl);
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else {
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    try {
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        byte[] encoded = crl.getEncoded();
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        implCRLs.add(new X509CRLImpl(encoded));
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } catch (CRLException ce) {
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        IOException ie = new IOException(ce.getMessage());
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ie.initCause(ce);
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw ie;
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Add the CRL set (tagged with [1] IMPLICIT)
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // to the signed data
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            signedData.putOrderedSetOf((byte)0xA1,
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    implCRLs.toArray(new X509CRLImpl[implCRLs.size()]));
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // signerInfos
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos);
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // making it a signed data block
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DerValue signedDataSeq = new DerValue(DerValue.tag_Sequence,
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                              signedData.toByteArray());
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // making it a content info sequence
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ContentInfo block = new ContentInfo(ContentInfo.SIGNED_DATA_OID,
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                            signedDataSeq);
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // writing out the contentInfo sequence
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        block.encode(out);
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This verifies a given SignerInfo.
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param info the signer information.
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param bytes the DER encoded content information.
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NoSuchAlgorithmException on unrecognized algorithms.
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SignatureException on signature handling errors.
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SignerInfo verify(SignerInfo info, byte[] bytes)
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    throws NoSuchAlgorithmException, SignatureException {
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return info.verify(this, bytes);
56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
568ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak     * This verifies a given SignerInfo.
569ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak     *
570ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak     * @param info the signer information.
571ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak     * @param dataInputStream the DER encoded content information.
572ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak     *
573ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak     * @exception NoSuchAlgorithmException on unrecognized algorithms.
574ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak     * @exception SignatureException on signature handling errors.
575ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak     */
576ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak    public SignerInfo verify(SignerInfo info, InputStream dataInputStream)
577ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak    throws NoSuchAlgorithmException, SignatureException, IOException {
578ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak        return info.verify(this, dataInputStream);
579ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak    }
580ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak
581ebe4f19cd62ed042845e23b7132859c88d91934bPrzemyslaw Szczepaniak    /**
58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns all signerInfos which self-verify.
58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param bytes the DER encoded content information.
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NoSuchAlgorithmException on unrecognized algorithms.
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SignatureException on signature handling errors.
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SignerInfo[] verify(byte[] bytes)
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    throws NoSuchAlgorithmException, SignatureException {
59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Vector<SignerInfo> intResult = new Vector<SignerInfo>();
59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < signerInfos.length; i++) {
59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            SignerInfo signerInfo = verify(signerInfos[i], bytes);
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (signerInfo != null) {
59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                intResult.addElement(signerInfo);
59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (intResult.size() != 0) {
60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            SignerInfo[] result = new SignerInfo[intResult.size()];
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            intResult.copyInto(result);
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return result;
60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return null;
60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns all signerInfos which self-verify.
61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NoSuchAlgorithmException on unrecognized algorithms.
61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SignatureException on signature handling errors.
61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SignerInfo[] verify()
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    throws NoSuchAlgorithmException, SignatureException {
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return verify(null);
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the version number of this PKCS7 block.
62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the version or null if version is not specified
62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         for the content type.
62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public  BigInteger getVersion() {
62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return version;
62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the message digest algorithms specified in this PKCS7 block.
63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the array of Digest Algorithms or null if none are specified
63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         for the content type.
63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public AlgorithmId[] getDigestAlgorithmIds() {
63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return  digestAlgorithmIds;
63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the content information specified in this PKCS7 block.
64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public ContentInfo getContentInfo() {
64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return contentInfo;
64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the X.509 certificates listed in this PKCS7 block.
64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a clone of the array of X.509 certificates or null if
64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         none are specified for the content type.
64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public X509Certificate[] getCertificates() {
65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (certificates != null)
65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return certificates.clone();
65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else
65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return null;
65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the X.509 crls listed in this PKCS7 block.
65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a clone of the array of X.509 crls or null if none
66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         are specified for the content type.
66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public X509CRL[] getCRLs() {
66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (crls != null)
66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return crls.clone();
66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else
66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return null;
66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the signer's information specified in this PKCS7 block.
67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the array of Signer Infos or null if none are specified
67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         for the content type.
67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SignerInfo[] getSignerInfos() {
67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return signerInfos;
67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the X.509 certificate listed in this PKCS7 block
68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * which has a matching serial number and Issuer name, or
68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * null if one is not found.
68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param serial the serial number of the certificate to retrieve.
68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param issuerName the Distinguished Name of the Issuer.
68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public X509Certificate getCertificate(BigInteger serial, X500Name issuerName) {
68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (certificates != null) {
68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (certIssuerNames == null)
68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                populateCertIssuerNames();
69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < certificates.length; i++) {
69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                X509Certificate cert = certificates[i];
69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                BigInteger thisSerial = cert.getSerialNumber();
69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (serial.equals(thisSerial)
69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    && issuerName.equals(certIssuerNames[i]))
69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                {
69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return cert;
69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return null;
70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Populate array of Issuer DNs from certificates and convert
70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * each Principal to type X500Name if necessary.
70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void populateCertIssuerNames() {
70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (certificates == null)
70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        certIssuerNames = new Principal[certificates.length];
71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < certificates.length; i++) {
71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            X509Certificate cert = certificates[i];
71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Principal certIssuerName = cert.getIssuerDN();
71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!(certIssuerName instanceof X500Name)) {
71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // must extract the original encoded form of DN for
71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // subsequent name comparison checks (converting to a
71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // String and back to an encoded DN could cause the
71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // types of String attribute values to be changed)
72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    X509CertInfo tbsCert =
72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        new X509CertInfo(cert.getTBSCertificate());
72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    certIssuerName = (Principal)
72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        tbsCert.get(CertificateIssuerName.NAME + "." +
72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    CertificateIssuerName.DN_NAME);
72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (Exception e) {
72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // error generating X500Name object from the cert's
72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // issuer DN, leave name as is.
72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            certIssuerNames[i] = certIssuerName;
73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the PKCS7 block in a printable string form.
73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toString() {
73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String out = "";
74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        out += contentInfo + "\n";
74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (version != null)
74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            out += "PKCS7 :: version: " + Debug.toHexString(version) + "\n";
74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (digestAlgorithmIds != null) {
74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            out += "PKCS7 :: digest AlgorithmIds: \n";
74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < digestAlgorithmIds.length; i++)
74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                out += "\t" + digestAlgorithmIds[i] + "\n";
74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (certificates != null) {
75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            out += "PKCS7 :: certificates: \n";
75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < certificates.length; i++)
75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                out += "\t" + i + ".   " + certificates[i] + "\n";
75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (crls != null) {
75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            out += "PKCS7 :: crls: \n";
75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < crls.length; i++)
75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                out += "\t" + i + ".   " + crls[i] + "\n";
75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (signerInfos != null) {
76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            out += "PKCS7 :: signer infos: \n";
76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (int i = 0; i < signerInfos.length; i++)
76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                out += ("\t" + i + ".  " + signerInfos[i] + "\n");
76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return out;
76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns true if this is a JDK1.1.x-style PKCS#7 block, and false
76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * otherwise.
77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isOldStyle() {
77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return this.oldStyle;
77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
774e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
775e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin    /**
776e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin     * For legacy reasons we need to return exactly the original encoded certificate bytes, instead
777e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin     * of letting the underlying implementation have a shot at re-encoding the data.
778e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin     */
779e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin    private static class VerbatimX509Certificate extends WrappedX509Certificate {
780e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        private byte[] encodedVerbatim;
781e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
782e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public VerbatimX509Certificate(X509Certificate wrapped, byte[] encodedVerbatim) {
783e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            super(wrapped);
784e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            this.encodedVerbatim = encodedVerbatim;
785e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
786e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
787e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
788e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public byte[] getEncoded() throws CertificateEncodingException {
789e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return encodedVerbatim;
790e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
791e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin    }
792e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
793e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin    private static class WrappedX509Certificate extends X509Certificate {
794e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        private final X509Certificate wrapped;
795e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
796e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public WrappedX509Certificate(X509Certificate wrapped) {
797e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            this.wrapped = wrapped;
798e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
799e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
800e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
801e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public Set<String> getCriticalExtensionOIDs() {
802e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getCriticalExtensionOIDs();
803e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
804e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
805e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
806e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public byte[] getExtensionValue(String oid) {
807e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getExtensionValue(oid);
808e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
809e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
810e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
811e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public Set<String> getNonCriticalExtensionOIDs() {
812e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getNonCriticalExtensionOIDs();
813e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
814e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
815e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
816e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public boolean hasUnsupportedCriticalExtension() {
817e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.hasUnsupportedCriticalExtension();
818e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
819e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
820e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
821e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public void checkValidity()
822e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                throws CertificateExpiredException, CertificateNotYetValidException {
823e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            wrapped.checkValidity();
824e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
825e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
826e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
827e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public void checkValidity(Date date)
828e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                throws CertificateExpiredException, CertificateNotYetValidException {
829e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            wrapped.checkValidity(date);
830e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
831e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
832e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
833e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public int getVersion() {
834e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getVersion();
835e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
836e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
837e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
838e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public BigInteger getSerialNumber() {
839e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getSerialNumber();
840e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
841e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
842e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
843e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public Principal getIssuerDN() {
844e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getIssuerDN();
845e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
846e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
847e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
848e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public Principal getSubjectDN() {
849e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getSubjectDN();
850e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
851e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
852e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
853e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public Date getNotBefore() {
854e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getNotBefore();
855e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
856e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
857e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
858e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public Date getNotAfter() {
859e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getNotAfter();
860e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
861e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
862e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
863e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public byte[] getTBSCertificate() throws CertificateEncodingException {
864e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getTBSCertificate();
865e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
866e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
867e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
868e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public byte[] getSignature() {
869e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getSignature();
870e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
871e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
872e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
873e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public String getSigAlgName() {
874e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getSigAlgName();
875e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
876e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
877e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
878e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public String getSigAlgOID() {
879e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getSigAlgOID();
880e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
881e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
882e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
883e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public byte[] getSigAlgParams() {
884e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getSigAlgParams();
885e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
886e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
887e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
888e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public boolean[] getIssuerUniqueID() {
889e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getIssuerUniqueID();
890e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
891e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
892e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
893e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public boolean[] getSubjectUniqueID() {
894e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getSubjectUniqueID();
895e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
896e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
897e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
898e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public boolean[] getKeyUsage() {
899e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getKeyUsage();
900e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
901e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
902e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
903e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public int getBasicConstraints() {
904e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getBasicConstraints();
905e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
906e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
907e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
908e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public byte[] getEncoded() throws CertificateEncodingException {
909e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getEncoded();
910e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
911e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
912e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
913e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
914e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                InvalidKeyException, NoSuchProviderException, SignatureException {
915e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            wrapped.verify(key);
916e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
917e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
918e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
919e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public void verify(PublicKey key, String sigProvider)
920e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
921e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                NoSuchProviderException, SignatureException {
922e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            wrapped.verify(key, sigProvider);
923e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
924e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
925e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
926e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public String toString() {
927e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.toString();
928e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
929e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
930e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
931e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public PublicKey getPublicKey() {
932e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getPublicKey();
933e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
934e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
935e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
936e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public List<String> getExtendedKeyUsage() throws CertificateParsingException {
937e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getExtendedKeyUsage();
938e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
939e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
940e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
941e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public Collection<List<?>> getIssuerAlternativeNames() throws CertificateParsingException {
942e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getIssuerAlternativeNames();
943e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
944e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
945e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
946e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public X500Principal getIssuerX500Principal() {
947e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getIssuerX500Principal();
948e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
949e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
950e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
951e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
952e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getSubjectAlternativeNames();
953e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
954e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
955e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
956e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public X500Principal getSubjectX500Principal() {
957e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            return wrapped.getSubjectX500Principal();
958e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
959e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin
960e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        @Override
961e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        public void verify(PublicKey key, Provider sigProvider) throws CertificateException,
962e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin                NoSuchAlgorithmException, InvalidKeyException, SignatureException {
963e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin            wrapped.verify(key, sigProvider);
964e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin        }
965e8eab1ee19e8536e78e35cff3bb8929cb3cd08beAlex Klyubin    }
96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
967