671 lines · 23.7 KB · Java
RawDownload
    }     /*     * Examines a signature timestamp token to generate a timestamp object.     *     * Examines the signer's unsigned attributes for a     * <tt>signatureTimestampToken</tt> attribute. If present,     * then it is parsed to extract the date and time at which the     * timestamp was generated.     *     * @param info A signer information element of a PKCS 7 block.     *     * @return A timestamp token or null if none is present.     * @throws IOException if an error is encountered while parsing the     *         PKCS7 data.     * @throws NoSuchAlgorithmException if an error is encountered while     *         verifying the PKCS7 object.     * @throws SignatureException if an error is encountered while     *         verifying the PKCS7 object.     * @throws CertificateException if an error is encountered while generating     *         the TSA's certpath.     */    private Timestamp getTimestamp(SignerInfo info)        throws IOException, NoSuchAlgorithmException, SignatureException,            CertificateException {         Timestamp timestamp = null;         // Extract the signer's unsigned attributes        PKCS9Attributes unsignedAttrs = info.getUnauthenticatedAttributes();        if (unsignedAttrs != null) {            PKCS9Attribute timestampTokenAttr =                unsignedAttrs.getAttribute("signatureTimestampToken");            if (timestampTokenAttr != null) {                PKCS7 timestampToken =                    new PKCS7((byte[])timestampTokenAttr.getValue());                // Extract the content (an encoded timestamp token info)                byte[] encodedTimestampTokenInfo =                    timestampToken.getContentInfo().getData();                // Extract the signer (the Timestamping Authority)                // while verifying the content                SignerInfo[] tsa =                    timestampToken.verify(encodedTimestampTokenInfo);                // Expect only one signer                ArrayList<X509Certificate> chain =                                tsa[0].getCertificateChain(timestampToken);                CertPath tsaChain = certificateFactory.generateCertPath(chain);                // Create a timestamp token info object                TimestampToken timestampTokenInfo =                    new TimestampToken(encodedTimestampTokenInfo);                // Create a timestamp object                timestamp =                    new Timestamp(timestampTokenInfo.getDate(), tsaChain);            }        }        return timestamp;    }     // for the toHex function    private static final char[] hexc =            {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};    /**     * convert a byte array to a hex string for debugging purposes     * @param data the binary data to be converted to a hex string     * @return an ASCII hex string     */     static String toHex(byte[] data) {         StringBuffer sb = new StringBuffer(data.length*2);         for (int i=0; i<data.length; i++) {            sb.append(hexc[(data[i] >>4) & 0x0f]);            sb.append(hexc[data[i] & 0x0f]);        }        return sb.toString();    }     // returns true if set contains signer    static boolean contains(CodeSigner[] set, CodeSigner signer)    {        for (int i = 0; i < set.length; i++) {            if (set[i].equals(signer))                return true;        }        return false;    }     // returns true if subset is a subset of set    static boolean isSubSet(CodeSigner[] subset, CodeSigner[] set)    {        // check for the same object        if (set == subset)            return true;         boolean match;        for (int i = 0; i < subset.length; i++) {            if (!contains(set, subset[i]))                return false;        }        return true;    }     /**     * returns true if signer contains exactly the same code signers as     * oldSigner and newSigner, false otherwise. oldSigner     * is allowed to be null.     */    static boolean matches(CodeSigner[] signers, CodeSigner[] oldSigners,        CodeSigner[] newSigners) {         // special case        if ((oldSigners == null) && (signers == newSigners))            return true;         boolean match;         // make sure all oldSigners are in signers        if ((oldSigners != null) && !isSubSet(oldSigners, signers))            return false;         // make sure all newSigners are in signers        if (!isSubSet(newSigners, signers)) {            return false;        }         // now make sure all the code signers in signers are        // also in oldSigners or newSigners         for (int i = 0; i < signers.length; i++) {            boolean found =                ((oldSigners != null) && contains(oldSigners, signers[i])) ||                contains(newSigners, signers[i]);            if (!found)                return false;        }        return true;    }     void updateSigners(CodeSigner[] newSigners,        Hashtable<String, CodeSigner[]> signers, String name) {         CodeSigner[] oldSigners = signers.get(name);         // search through the cache for a match, go in reverse order        // as we are more likely to find a match with the last one        // added to the cache         CodeSigner[] cachedSigners;        for (int i = signerCache.size() - 1; i != -1; i--) {            cachedSigners = signerCache.get(i);            if (matches(cachedSigners, oldSigners, newSigners)) {                signers.put(name, cachedSigners);                return;            }        }         if (oldSigners == null) {            cachedSigners = newSigners;        } else {            cachedSigners =                new CodeSigner[oldSigners.length + newSigners.length];            System.arraycopy(oldSigners, 0, cachedSigners, 0,                oldSigners.length);            System.arraycopy(newSigners, 0, cachedSigners, oldSigners.length,                newSigners.length);        }        signerCache.add(cachedSigners);        signers.put(name, cachedSigners);    }}

Lines 501–671 of 671. Previous lines