// recupera il signing time di un firmatario
  private static Date getSigningTime(SignerInformation signer) throws FirmapiuException {
    AttributeTable signedAttr = signer.getSignedAttributes();
    Attribute signingTimeAttr = signedAttr.get(CMSAttributes.signingTime);
    if (signingTimeAttr != null) {
      Enumeration<?> en = signingTimeAttr.getAttrValues().getObjects();

      Date signingTime = null;

      Object obj = en.nextElement();
      try {
        if (obj instanceof ASN1UTCTime) {
          ASN1UTCTime asn1Time = (ASN1UTCTime) obj;
          signingTime = asn1Time.getDate();
        } else if (obj instanceof DERUTCTime) {
          DERUTCTime derTime = (DERUTCTime) obj;
          signingTime = derTime.getDate();
        }
        return signingTime;
      } catch (ParseException e) {
        // TODO eccezioni ammodo
        throw new FirmapiuException();
      }

    } else {
      // non ha trovato il signing time come attributo
      // TODO eccezioni ammodo
      throw new FirmapiuException();
    }
  } // fine metodo
 // controlla che nel firmatario sia presente l'attributo ESSCertIDv2 e che esso sia valido
 // in questo caso la busta crittografica è espressa correttamente nel formato CADES-BES secondo
 // la  DELIBERAZIONE ministeriale del N . 45 DEL 21 MAGGIO 2009
 private boolean isLegallySigned(SignerInformation signer, X509CertificateHolder cert)
     throws FirmapiuException, NoSuchAlgorithmException, IOException {
   AttributeTable signAttr = signer.getSignedAttributes();
   if (signAttr == null) throw new FirmapiuException(VERIFY_SIGNER_SIGNINGATTRIBUTE_NOTFOUND);
   Attribute attr = signAttr.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2);
   if (attr == null) throw new FirmapiuException(VERIFY_SIGNER_SIGNINGATTRIBUTE_NOTFOUND);
   ASN1Sequence sequence = ASN1Sequence.getInstance(attr.getAttrValues().getObjectAt(0));
   SigningCertificateV2 scv2 = SigningCertificateV2.getInstance(sequence);
   ESSCertIDv2[] essCert = scv2.getCerts();
   if (essCert == null || essCert.length < 1)
     throw new FirmapiuException(VERIFY_SIGNER_SIGNINGATTRIBUTE_NOTFOUND);
   // controlla l'hash del certificato se si restituisce true se no restituisce no
   // aggiungere hash del certificato di sottoscrizione
   String digestAlgorithm = "SHA-256";
   MessageDigest sha = null;
   sha = MessageDigest.getInstance(digestAlgorithm);
   byte[] digestedCert = sha.digest(cert.getEncoded());
   byte[] essCertHash = essCert[0].getCertHash();
   // affinché la firma sia valida digestCert e essCertHash devono essere uguali
   if (digestedCert.length != essCertHash.length) return false;
   else {
     for (int i = 0; i < digestedCert.length; i++)
       if (digestedCert[i] != essCertHash[i]) {
         return false;
       }
     return true;
   } // fine if
 } // fine metodo
  public void multipartMixedTest(MimeBodyPart part1, MimeBodyPart part2) throws Exception {
    MimeMultipart mp = new MimeMultipart();

    mp.addBodyPart(part1);
    mp.addBodyPart(part2);

    MimeBodyPart m = new MimeBodyPart();

    m.setContent(mp);

    MimeMultipart smm =
        generateMultiPartRsa("SHA1withRSA", m, SMIMESignedGenerator.RFC3851_MICALGS);
    SMIMESigned s = new SMIMESigned(smm);

    verifySigners(s.getCertificates(), s.getSignerInfos());

    AttributeTable attr =
        ((SignerInformation) s.getSignerInfos().getSigners().iterator().next())
            .getSignedAttributes();

    Attribute a = attr.get(CMSAttributes.messageDigest);
    byte[] contentDigest =
        ASN1OctetString.getInstance(a.getAttrValues().getObjectAt(0)).getOctets();

    mp = (MimeMultipart) m.getContent();
    ContentType contentType = new ContentType(mp.getContentType());
    String boundary = "--" + contentType.getParameter("boundary");

    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    LineOutputStream lOut = new LineOutputStream(bOut);

    Enumeration headers = m.getAllHeaderLines();
    while (headers.hasMoreElements()) {
      lOut.writeln((String) headers.nextElement());
    }

    lOut.writeln(); // CRLF separator

    lOut.writeln(boundary);
    writePart(mp.getBodyPart(0), bOut);
    lOut.writeln(); // CRLF terminator

    lOut.writeln(boundary);
    writePart(mp.getBodyPart(1), bOut);
    lOut.writeln();

    lOut.writeln(boundary + "--");

    MessageDigest dig = MessageDigest.getInstance("SHA1", BC);

    assertTrue(Arrays.equals(contentDigest, dig.digest(bOut.toByteArray())));
  }
  public void testMimeMultipart() throws Exception {
    MimeBodyPart m = createMultipartMessage();

    List certList = new ArrayList();

    certList.add(_signCert);
    certList.add(_origCert);

    Store certs = new JcaCertStore(certList);

    ASN1EncodableVector signedAttrs = generateSignedAttributes();

    SMIMESignedGenerator gen = new SMIMESignedGenerator("binary");

    gen.addSignerInfoGenerator(
        new JcaSimpleSignerInfoGeneratorBuilder()
            .setProvider(BC)
            .setSignedAttributeGenerator(new AttributeTable(signedAttrs))
            .build("SHA1withRSA", _signKP.getPrivate(), _signCert));
    gen.addCertificates(certs);

    MimeMultipart mm = gen.generate(m);

    SMIMESigned s = new SMIMESigned(mm);

    verifySigners(s.getCertificates(), s.getSignerInfos());

    byte[] contentDigest = (byte[]) gen.getGeneratedDigests().get(SMIMESignedGenerator.DIGEST_SHA1);

    AttributeTable table =
        ((SignerInformation) s.getSignerInfos().getSigners().iterator().next())
            .getSignedAttributes();
    Attribute hash = table.get(CMSAttributes.messageDigest);

    assertTrue(
        MessageDigest.isEqual(
            contentDigest, ((ASN1OctetString) hash.getAttrValues().getObjectAt(0)).getOctets()));
  }