/** * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS API. * * @return the X509Certificate * @throws IOException if an I/O error occured */ private ContentInfo readPKCS7(String endMarker) throws IOException { String line; StringBuffer buf = new StringBuffer(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); while ((line = readLine()) != null) { if (line.indexOf(endMarker) != -1) { break; } line = line.trim(); buf.append(line.trim()); Base64.decode(buf.substring(0, (buf.length() / 4) * 4), bOut); buf.delete(0, (buf.length() / 4) * 4); } if (buf.length() != 0) { throw new IOException("base64 data appears to be truncated"); } if (line == null) { throw new IOException(endMarker + " not found"); } try { ASN1InputStream aIn = new ASN1InputStream(bOut.toByteArray()); return ContentInfo.getInstance(aIn.readObject()); } catch (Exception e) { throw new PEMException("problem parsing PKCS7 object: " + e.toString(), e); } }
/** * Fetches the signature time-stamp attributes from a SignerInformation object. Checks that the * MessageImprint for each time-stamp matches the signature field. (see RFC 3161 Appendix A). * * @param signerInfo a SignerInformation to search for time-stamps * @param provider an optional provider to use to create MessageDigest instances * @return a collection of TimeStampToken objects * @throws TSPValidationException */ public static Collection getSignatureTimestamps(SignerInformation signerInfo, Provider provider) throws TSPValidationException { List timestamps = new ArrayList(); AttributeTable unsignedAttrs = signerInfo.getUnsignedAttributes(); if (unsignedAttrs != null) { ASN1EncodableVector allTSAttrs = unsignedAttrs.getAll(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken); for (int i = 0; i < allTSAttrs.size(); ++i) { Attribute tsAttr = (Attribute) allTSAttrs.get(i); ASN1Set tsAttrValues = tsAttr.getAttrValues(); for (int j = 0; j < tsAttrValues.size(); ++j) { try { ContentInfo contentInfo = ContentInfo.getInstance(tsAttrValues.getObjectAt(j).getDERObject()); TimeStampToken timeStampToken = new TimeStampToken(contentInfo); TimeStampTokenInfo tstInfo = timeStampToken.getTimeStampInfo(); MessageDigest digest = createDigestInstance(tstInfo.getMessageImprintAlgOID(), provider); byte[] expectedDigest = digest.digest(signerInfo.getSignature()); if (!Arrays.constantTimeAreEqual(expectedDigest, tstInfo.getMessageImprintDigest())) { throw new TSPValidationException("Incorrect digest in message imprint"); } timestamps.add(timeStampToken); } catch (NoSuchAlgorithmException e) { throw new TSPValidationException("Unknown hash algorithm specified in timestamp"); } catch (Exception e) { throw new TSPValidationException("Timestamp could not be parsed"); } } } } return timestamps; }