Example #1
0
  protected void processPKCS12FileFormatAndAddToCertificates(
      ByteArrayInputStream inputStream, ArrayList<X509Certificate> certificates)
      throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
          UnrecoverableKeyException {
    KeyStore localKeyStore = KeyStore.getInstance("PKCS12");
    localKeyStore.load(
        inputStream, keyStorePassword == null ? null : keyStorePassword.toCharArray());

    IOUtils.closeQuietly(inputStream);

    Enumeration<String> aliases = localKeyStore.aliases();

    // even though we are iterating over this enumeration, we
    // are really expecting only one alias
    while (aliases.hasMoreElements()) {
      String alias = aliases.nextElement();

      Certificate cert = localKeyStore.getCertificate(alias);
      if (cert != null && cert instanceof X509Certificate) {
        X509Certificate addCert;

        // check if there is private key
        Key key =
            localKeyStore.getKey(
                alias, keyStorePassword == null ? null : keyStorePassword.toCharArray());
        if (key != null && key instanceof PrivateKey) {
          addCert = X509CertificateEx.fromX509Certificate((X509Certificate) cert, (PrivateKey) key);
          certificates.add(addCert);
        }
      }
    }
  }
  /**
   * Decrypts an entity with the provided certificates' private key.
   *
   * @param encryptedEntity The entity that will be decrypted.
   * @param decryptingCertificate The certificates whose private keys will be used to decrypt the
   *     message.
   * @return A MimeEntity containing the decrypted part.
   */
  public MimeEntity decrypt(
      MimeEntity encryptedEntity, Collection<X509CertificateEx> decryptingCertificates) {
    if (decryptingCertificates == null || decryptingCertificates.size() == 0) {
      throw new IllegalArgumentException();
    }

    MimeEntity retEntity = null;
    try {
      if (LOGGER.isDebugEnabled()) {
        byte[] encryptedContent = encryptedEntity.getContentAsBytes();
        writePreDecrypt(encryptedContent);
      }

      SMIMEEnveloped m = new SMIMEEnveloped(encryptedEntity);

      X509CertificateEx decryptCert = decryptingCertificates.iterator().next();

      RecipientId recId = generateRecipientSelector(decryptCert);

      RecipientInformationStore recipients = m.getRecipientInfos();
      RecipientInformation recipient = recipients.get(recId);

      byte[] decryptedPayload =
          recipient.getContent(decryptCert.getPrivateKey(), CryptoExtensions.getJCEProviderName());

      if (LOGGER.isDebugEnabled()) {
        writePostDecrypt(decryptedPayload);
      }

      ByteArrayInputStream inStream = new ByteArrayInputStream(decryptedPayload);

      retEntity = new MimeEntity(inStream);

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

    return retEntity;
  }
  private X509Certificate certFromData(byte[] data) {
    X509Certificate retVal = null;
    try {
      ByteArrayInputStream bais = new ByteArrayInputStream(data);

      // lets try this a as a PKCS12 data stream first
      try {
        KeyStore localKeyStore =
            KeyStore.getInstance("PKCS12", CryptoExtensions.getJCEProviderName());

        localKeyStore.load(bais, "".toCharArray());
        Enumeration<String> aliases = localKeyStore.aliases();

        // we are really expecting only one alias
        if (aliases.hasMoreElements()) {
          String alias = aliases.nextElement();
          X509Certificate cert = (X509Certificate) localKeyStore.getCertificate(alias);

          // check if there is private key
          Key key = localKeyStore.getKey(alias, "".toCharArray());
          if (key != null && key instanceof PrivateKey) {
            retVal = X509CertificateEx.fromX509Certificate(cert, (PrivateKey) key);
          } else retVal = cert;
        }
      } catch (Exception e) {
        // must not be a PKCS12 stream, go on to next step
      }

      if (retVal == null) {
        // try X509 certificate factory next
        bais.reset();
        bais = new ByteArrayInputStream(data);

        retVal =
            (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(bais);
      }
      bais.close();
    } catch (Exception e) {
      throw new NHINDException("Data cannot be converted to a valid X.509 Certificate", e);
    }

    return retVal;
  }
  /**
   * Decrypts an entity with the provided certificate's private key.
   *
   * @param encryptedEntity The entity that will be decrypted.
   * @param decryptingCertificate The certificate whose private key will be used to decrypt the
   *     message.
   * @return A MimeEntity containing the decrypted part.
   */
  public MimeEntity decrypt(MimeEntity encryptedEntity, X509CertificateEx decryptingCertificate) {
    if (encryptedEntity == null || decryptingCertificate == null) {
      throw new IllegalArgumentException();
    }

    if (!decryptingCertificate.hasPrivateKey()) {
      throw new IllegalArgumentException("Certificate has no private key");
    }

    encryptedEntity.verifyContentType(SMIMEStandard.EncryptedContentTypeHeaderValue);
    encryptedEntity.verifyTransferEncoding(MimeStandard.TransferEncodingBase64);

    Collection<X509CertificateEx> certs = new ArrayList<X509CertificateEx>();
    certs.add(decryptingCertificate);

    MimeEntity retVal = this.decrypt(encryptedEntity, certs);

    //
    // And turn the decrypted bytes back into an entity
    //
    return retVal;
  }
  private X509Certificate certFromData(byte[] data) {
    X509Certificate retVal = null;
    try {
      // first check for wrapped data
      final CertContainer container = CertUtils.toCertContainer(data);
      if (container.getWrappedKeyData() != null) {
        // this is a wrapped key
        // make sure we have a KeyStoreManager configured
        if (this.mgr == null) {
          throw new NHINDException(
              AgentError.Unexpected,
              "Resolved certifiate has wrapped data, but resolver has not been configured to unwrap it.");
        }

        // create a new wrapped certificate object
        retVal =
            WrappedOnDemandX509CertificateEx.fromX509Certificate(
                mgr, container.getCert(), container.getWrappedKeyData());
        return retVal;
      }

      ByteArrayInputStream bais = new ByteArrayInputStream(data);

      // lets try this a as a PKCS12 data stream first
      try {
        KeyStore localKeyStore =
            KeyStore.getInstance("PKCS12", CryptoExtensions.getJCEProviderName());

        localKeyStore.load(bais, "".toCharArray());
        Enumeration<String> aliases = localKeyStore.aliases();

        // we are really expecting only one alias
        if (aliases.hasMoreElements()) {
          String alias = aliases.nextElement();
          X509Certificate cert = (X509Certificate) localKeyStore.getCertificate(alias);

          // check if there is private key
          Key key = localKeyStore.getKey(alias, "".toCharArray());
          if (key != null && key instanceof PrivateKey) {
            retVal = X509CertificateEx.fromX509Certificate(cert, (PrivateKey) key);
          } else retVal = cert;
        }
      } catch (Exception e) {
        // must not be a PKCS12 stream, go on to next step
      }

      if (retVal == null) {
        // try X509 certificate factory next
        bais.reset();
        bais = new ByteArrayInputStream(data);

        retVal =
            (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(bais);
      }
      bais.close();
    } catch (Exception e) {
      throw new NHINDException("Data cannot be converted to a valid X.509 Certificate", 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;
    }