/**
   * Encrypts an entity using the provided certificates.
   *
   * @param entity The entity that will be encrypted.
   * @param encryptingCertificate The public certificates that will be used to encrypt the message.
   * @return A MimeEntity containing the encrypted part.
   */
  public MimeEntity encrypt(MimeEntity entity, Collection<X509Certificate> encryptingCertificates) {
    if (entity == null) {
      throw new IllegalArgumentException();
    }

    MimeBodyPart partToEncrypt = entity;
    MimeBodyPart encryptedPart = this.encrypt(partToEncrypt, encryptingCertificates);
    MimeEntity encryptedEntity = null;

    try {
      byte[] encBytes = EntitySerializer.Default.serializeToBytes(encryptedPart);
      ByteArrayInputStream inStream =
          new ByteArrayInputStream(EntitySerializer.Default.serializeToBytes(encryptedPart));
      encryptedEntity = new MimeEntity(inStream);

      if (LOGGER.isDebugEnabled()) {
        writePostEncypt(encBytes);
      }

      encryptedEntity.setHeader(
          MimeStandard.ContentTypeHeader, SMIMEStandard.EncryptedContentTypeHeaderValue);

    } catch (Exception e) {
      throw new MimeException(MimeError.Unexpected, e);
    }

    return encryptedEntity;
  }
  /**
   * Extracts the ASN1 encoded signature data from the signed entity.
   *
   * @param entity The entity containing the original signed part and the message signature.
   * @return A CMSSignedData object that contains the ASN1 encoded signature data of the message.
   */
  public CMSSignedData deserializeSignatureEnvelope(SignedEntity entity) {

    if (entity == null) {
      throw new NHINDException();
    }

    CMSSignedData signed = null;

    try {
      // signed = new SMIMESigned(entity.getMimeMultipart());
      byte[] messageBytes = EntitySerializer.Default.serializeToBytes(entity.getContent());
      MimeBodyPart signedContent = null;

      signedContent = new MimeBodyPart(new ByteArrayInputStream(messageBytes));

      // signed = new CMSSignedData(new CMSProcessableBodyPartInbound(signedContent),
      // entity.getMimeMultipart().getBodyPart(1).getInputStream());
      signed =
          new CMSSignedData(
              new CMSProcessableBodyPart(signedContent),
              entity.getMimeMultipart().getBodyPart(1).getInputStream());

    } catch (Exception e) {
      e.printStackTrace();
      throw new MimeException(MimeError.Unexpected, e);
    }

    return signed;
  }
  private MimeBodyPart createEncryptedEnvelope(
      MimeBodyPart bodyPart, Collection<X509Certificate> encryptingCertificates) {
    if (bodyPart == null || encryptingCertificates == null || encryptingCertificates.size() == 0) {
      throw new IllegalArgumentException();
    }

    if (LOGGER.isDebugEnabled()) {
      writePreEncypt(EntitySerializer.Default.serializeToBytes(bodyPart));
    }

    SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();

    for (X509Certificate cert : encryptingCertificates) gen.addKeyTransRecipient(cert);

    MimeBodyPart retVal = null;

    try {
      retVal =
          gen.generate(
              bodyPart,
              toEncyAlgorithmOid(this.m_encryptionAlgorithm),
              CryptoExtensions.getJCEProviderName());
    } catch (Exception e) {
      throw new MimeException(MimeError.Unexpected, e);
    }

    return retVal;
  }
  public CMSSignedData deserializeEnvelopedSignature(MimeEntity envelopeEntity) {
    if (envelopeEntity == null) {
      throw new SignatureException(SignatureError.NullEntity);
    }

    if (!SMIMEStandard.isSignedEnvelope(envelopeEntity)) {
      throw new SignatureException(SignatureError.NotSignatureEnvelope);
    }

    byte[] envelopeBytes = EntitySerializer.Default.serializeToBytes(envelopeEntity);

    return this.deserializeEnvelopedSignature(envelopeBytes);
  }
  /**
   * Signs an entity with the provided certificates.
   *
   * @param message The entity that will be signed.
   * @param signingCertificates The certificates used to sign the message.
   * @return A signed entity that consists of a multipart/signed entity containing the original
   *     entity and a message signature.
   */
  public SignedEntity sign(MimeEntity entity, Collection<X509Certificate> signingCertificates) {
    if (entity == null) {
      throw new IllegalArgumentException();
    }

    byte[] messageBytes =
        EntitySerializer.Default.serializeToBytes(
            entity); // Serialize message out as ASCII encoded...

    MimeMultipart mm = this.createSignatureEntity(messageBytes, signingCertificates);
    SignedEntity retVal = null;

    try {

      retVal = new SignedEntity(new ContentType(mm.getContentType()), mm);
    } catch (ParseException e) {
      throw new MimeException(MimeError.InvalidHeader, e);
    }

    return retVal;
  }
    protected SignerInformation createSignerInformation() throws Exception {
      X509CertificateEx internalCert = TestUtils.getInternalCert("user1");
      String testMessage = TestUtils.readResource("MultipartMimeMessage.txt");

      MimeMessage entity = EntitySerializer.Default.deserialize(testMessage);
      Message message = new Message(entity);

      MimeEntity entityToSig = message.extractEntityForSignature(true);

      byte[] messageBytes =
          EntitySerializer.Default.serializeToBytes(entityToSig); // Serialize message out as
      // ASCII encoded...

      MimeBodyPart partToSign = null;

      try {
        partToSign = new MimeBodyPart(new ByteArrayInputStream(messageBytes));
      } catch (Exception e) {
      }

      SMIMESignedGenerator gen = new SMIMESignedGenerator();

      ASN1EncodableVector signedAttrs = new ASN1EncodableVector();
      SMIMECapabilityVector caps = new SMIMECapabilityVector();

      caps.addCapability(SMIMECapability.dES_EDE3_CBC);
      caps.addCapability(SMIMECapability.rC2_CBC, 128);
      caps.addCapability(SMIMECapability.dES_CBC);
      caps.addCapability(new DERObjectIdentifier("1.2.840.113549.1.7.1"));
      caps.addCapability(PKCSObjectIdentifiers.x509Certificate);
      signedAttrs.add(new SMIMECapabilitiesAttribute(caps));

      List<X509Certificate> certList = new ArrayList<X509Certificate>();

      gen.addSigner(
          internalCert.getPrivateKey(),
          internalCert,
          SMIMESignedGenerator.DIGEST_SHA1,
          new AttributeTable(signedAttrs),
          null);
      certList.add(internalCert);

      theGetCertificates = certList;

      MimeMultipart retVal = null;

      CertStore certsAndcrls =
          CertStore.getInstance(
              "Collection",
              new CollectionCertStoreParameters(certList),
              CryptoExtensions.getJCEProviderName());
      gen.addCertificatesAndCRLs(certsAndcrls);

      retVal = gen.generate(partToSign, CryptoExtensions.getJCEProviderName());

      ByteArrayOutputStream oStream = new ByteArrayOutputStream();
      retVal.writeTo(oStream);
      oStream.flush();
      byte[] serialzedBytes = oStream.toByteArray();

      ByteArrayDataSource dataSource =
          new ByteArrayDataSource(serialzedBytes, retVal.getContentType());

      MimeMultipart verifyMM = new MimeMultipart(dataSource);

      CMSSignedData signeddata =
          new CMSSignedData(
              new CMSProcessableBodyPartInbound(partToSign),
              verifyMM.getBodyPart(1).getInputStream());
      SignerInformationStore signers = signeddata.getSignerInfos();
      Collection c = signers.getSigners();
      Iterator it = c.iterator();
      while (it.hasNext()) {
        SignerInformation signer = (SignerInformation) it.next();
        return signer;
      }
      return null;
    }