Search in sources :

Example 1 with RecipientId

use of org.bouncycastle.cms.RecipientId in project nhin-d by DirectProject.

the class SMIMECryptographerImpl method decrypt.

/**
     * 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()) {
            final byte[] encryptedContent = encryptedEntity.getContentAsBytes();
            writePreDecrypt(encryptedContent);
        }
        final SMIMEEnveloped m = new SMIMEEnveloped(encryptedEntity);
        if (!this.isAllowedEncryptionAlgorithm(m.getEncryptionAlgOID()))
            throw new NHINDException(MimeError.DisallowedEncryptionAlgorithm, "The encryption algorithm " + m.getEncryptionAlgOID() + " is not allowed");
        for (X509CertificateEx decryptCert : decryptingCertificates) {
            final RecipientId recId = generateRecipientSelector(decryptCert);
            final RecipientInformationStore recipients = m.getRecipientInfos();
            final DirectRecipientInformation recipient = decFactory.createInstance(recipients.get(recId), m);
            if (recipient == null)
                continue;
            final byte[] decryptedPayload = recipient.getDecryptedContent(decryptCert.getPrivateKey());
            if (LOGGER.isDebugEnabled()) {
                writePostDecrypt(decryptedPayload);
            }
            final ByteArrayInputStream inStream = new ByteArrayInputStream(decryptedPayload);
            retEntity = new MimeEntity(inStream);
            break;
        }
    } catch (MessagingException e) {
        throw new MimeException(MimeError.InvalidMimeEntity, e);
    } catch (Exception e) {
        throw new MimeException(MimeError.Unexpected, e);
    }
    if (retEntity == null) {
        throw new NHINDException(MimeError.Unexpected, "None of the the provided decryption certs were found in message's RecipientsInfo set.");
    }
    return retEntity;
}
Also used : RecipientId(org.bouncycastle.cms.RecipientId) MessagingException(javax.mail.MessagingException) DirectRecipientInformation(org.nhindirect.stagent.cryptography.activekeyops.DirectRecipientInformation) SMIMEEnveloped(org.bouncycastle.mail.smime.SMIMEEnveloped) NHINDException(org.nhindirect.stagent.NHINDException) MessagingException(javax.mail.MessagingException) MimeException(org.nhindirect.stagent.mail.MimeException) NHINDException(org.nhindirect.stagent.NHINDException) ParseException(javax.mail.internet.ParseException) IOException(java.io.IOException) SignatureValidationException(org.nhindirect.stagent.SignatureValidationException) X509CertificateEx(org.nhindirect.stagent.cert.X509CertificateEx) ByteArrayInputStream(java.io.ByteArrayInputStream) MimeEntity(org.nhindirect.stagent.mail.MimeEntity) RecipientInformationStore(org.bouncycastle.cms.RecipientInformationStore) MimeException(org.nhindirect.stagent.mail.MimeException)

Example 2 with RecipientId

use of org.bouncycastle.cms.RecipientId in project ats-framework by Axway.

the class SMimePackageEncryptor method decrypt.

@PublicAtsApi
public Package decrypt(Package sourcePackage) throws ActionException {
    // for connection management to IMAP store
    boolean storeReconnected = false;
    if (sourcePackage instanceof MimePackage) {
        try {
            storeReconnected = ((MimePackage) sourcePackage).reconnectStoreIfClosed();
        } catch (MessagingException ex) {
            throw new ActionException("Could not reopen IMAP connection", ex);
        }
    }
    try {
        KeyStore ks = getKeystore();
        RecipientId recId = new JceKeyTransRecipientId((X509Certificate) ks.getCertificate(aliasOrCN));
        MimeMessage msg = getMimeMessage(sourcePackage);
        SMIMEEnveloped m = new SMIMEEnveloped(msg);
        RecipientInformationStore recipients = m.getRecipientInfos();
        RecipientInformation recipient = recipients.get(recId);
        PrivateKey privateKey = (PrivateKey) ks.getKey(aliasOrCN, certPassword.toCharArray());
        JceKeyTransRecipient jceKey = new JceKeyTransEnvelopedRecipient(privateKey).setProvider(BouncyCastleProvider.PROVIDER_NAME);
        MimeBodyPart result = null;
        try {
            result = SMIMEUtil.toMimeBodyPart(recipient.getContent(jceKey));
            if (LOG.isDebugEnabled()) {
                LOG.debug("Successfully decrypted message with subject '" + msg.getSubject() + "' with private key alias: " + aliasOrCN);
            }
        } catch (SMIMEException e) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Could not decrypt message with subject '" + sourcePackage.getSubject() + "' with private key alias '" + aliasOrCN + "'", e);
            }
        }
        SMIMESigned signedMessage = null;
        MimeMessage decryptedMsg = new MimeMessage(Session.getInstance(new Properties()));
        if (result != null) {
            Object content = result.getContent();
            Enumeration<?> hLineEnum = msg.getAllHeaderLines();
            while (hLineEnum.hasMoreElements()) {
                decryptedMsg.addHeaderLine((String) hLineEnum.nextElement());
            }
            decryptedMsg.setContent(content, result.getContentType());
            // in order getPlainTextBody getHtmlTextBody to work as they do not work with attachments
            decryptedMsg.removeHeader("Content-Disposition");
            // check if the message is signed
            try {
                if (content instanceof MimeMultipart) {
                    MimeMultipart multipartContent = (MimeMultipart) content;
                    if (multipartContent.getContentType() != null && multipartContent.getContentType().toLowerCase().contains(CONTENT_TYPE_MULTIPART_SIGNED)) {
                        signedMessage = new SMIMESigned(multipartContent);
                    }
                } else if (content instanceof SMIMESigned) {
                    signedMessage = (SMIMESigned) content;
                } else if (content instanceof BASE64DecoderStream) {
                    // com.sun.mail.util.BASE64DecoderStream - JavaMail API dependency. Seems still available
                    // in JavaMail 2.0 so not an issue if using other non-Oracle/OpenJDK JVMs
                    // will throw exception if not signed
                    signedMessage = new SMIMESigned(decryptedMsg);
                }
            } catch (Exception e) {
            // the message is not signed
            // log.debug( "Could not construct signed message instance", e );
            }
        }
        if (signedMessage != null) {
            // remove signature from the message
            decryptedMsg.setContent(signedMessage.getContent().getContent(), signedMessage.getContent().getContentType());
            MimePackage mimePackage = new MimePackage(decryptedMsg);
            // keep the SMIMESigned message for further signature verification
            mimePackage.setSMIMESignedMessage(signedMessage);
            return mimePackage;
        }
        return new MimePackage(decryptedMsg);
    } catch (Exception e) {
        throw new ActionException(DECRYPTION_EXCEPTION, e);
    } finally {
        if (storeReconnected) {
            // and sourcePackage should be instanceof MimePackage
            try {
                ((MimePackage) sourcePackage).closeStoreConnection(true);
            } catch (MessagingException ex) {
                // do not hide possible exception thrown in catch block
                LOG.debug(ex);
            }
        }
    }
}
Also used : JceKeyTransRecipient(org.bouncycastle.cms.jcajce.JceKeyTransRecipient) SMIMESigned(org.bouncycastle.mail.smime.SMIMESigned) JceKeyTransRecipientId(org.bouncycastle.cms.jcajce.JceKeyTransRecipientId) RecipientId(org.bouncycastle.cms.RecipientId) PrivateKey(java.security.PrivateKey) MessagingException(javax.mail.MessagingException) BASE64DecoderStream(com.sun.mail.util.BASE64DecoderStream) JceKeyTransRecipientId(org.bouncycastle.cms.jcajce.JceKeyTransRecipientId) ActionException(com.axway.ats.action.model.ActionException) JceKeyTransEnvelopedRecipient(org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient) Properties(java.util.Properties) KeyStore(java.security.KeyStore) SMIMEEnveloped(org.bouncycastle.mail.smime.SMIMEEnveloped) MessagingException(javax.mail.MessagingException) ActionException(com.axway.ats.action.model.ActionException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) MimePackage(com.axway.ats.action.objects.MimePackage) RecipientInformation(org.bouncycastle.cms.RecipientInformation) MimeMessage(javax.mail.internet.MimeMessage) MimeMultipart(javax.mail.internet.MimeMultipart) RecipientInformationStore(org.bouncycastle.cms.RecipientInformationStore) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) MimeBodyPart(javax.mail.internet.MimeBodyPart) PublicAtsApi(com.axway.ats.common.PublicAtsApi)

Example 3 with RecipientId

use of org.bouncycastle.cms.RecipientId in project nhin-d by DirectProject.

the class MessagaeDecryptor method main.

public static void main(String[] args) {
    try {
        final KeyStore store = KeyStore.getInstance("pkcs12");
        store.load(FileUtils.openInputStream(new File("/users/gm2552/Desktop/ops.p12")), "".toCharArray());
        final String alias = store.aliases().nextElement();
        final PrivateKey entry = (PrivateKey) store.getKey(alias, "".toCharArray());
        final X509Certificate cert = (X509Certificate) store.getCertificate(alias);
        /*
			for (String arg :args)
			{
				if (arg )
			}
			*/
        //String encryptedStuff = FileUtils.readFileToString(new File("users/gm2552/Desktop/cry.eml"));
        InputStream inStream = FileUtils.openInputStream(new File("/users/gm2552/Desktop/cry2.eml"));
        MimeBodyPart part = new MimeBodyPart(inStream);
        final SMIMEEnveloped m = new SMIMEEnveloped(part);
        RecipientId recId = new RecipientId();
        recId.setIssuer(cert.getIssuerX500Principal().getEncoded());
        recId.setSerialNumber(cert.getSerialNumber());
        final RecipientInformationStore recipients = m.getRecipientInfos();
        final DirectRecipientInformation recipient = new SplitDirectRecipientInformationFactory().createInstance(recipients.get(recId), m);
        final byte[] decryptedPayload = recipient.getDecryptedContent(entry);
        System.out.println("Alg OID: " + m.getEncryptionAlgOID());
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : PrivateKey(java.security.PrivateKey) RecipientId(org.bouncycastle.cms.RecipientId) InputStream(java.io.InputStream) DirectRecipientInformation(org.nhindirect.stagent.cryptography.activekeyops.DirectRecipientInformation) KeyStore(java.security.KeyStore) SMIMEEnveloped(org.bouncycastle.mail.smime.SMIMEEnveloped) X509Certificate(java.security.cert.X509Certificate) SplitDirectRecipientInformationFactory(org.nhindirect.stagent.cryptography.activekeyops.SplitDirectRecipientInformationFactory) RecipientInformationStore(org.bouncycastle.cms.RecipientInformationStore) MimeBodyPart(javax.mail.internet.MimeBodyPart) File(java.io.File)

Example 4 with RecipientId

use of org.bouncycastle.cms.RecipientId in project nhin-d by DirectProject.

the class SMIMECryptographerImpl method generateRecipientSelector.

/*
     * Construct an RecipientId.  Added private function to support multiple versions of BC libraries.
     */
private RecipientId generateRecipientSelector(X509Certificate decryptCert) {
    RecipientId retVal = null;
    Class<RecipientId> loadClass = null;
    try {
        // support for bcmail-jdk15-146
        loadClass = (Class<RecipientId>) getClass().getClassLoader().loadClass("org.bouncycastle.cms.jcajce.JceKeyTransRecipientId");
        Constructor<RecipientId> constructor = loadClass.getConstructor(X509Certificate.class);
        retVal = constructor.newInstance(decryptCert);
    } catch (Throwable e) {
        if (LOGGER.isDebugEnabled()) {
            StringBuilder builder = new StringBuilder("bcmail-jdk15-146 org.bouncycastle.cms.jcajce.JceKeyTransRecipientId class not found.");
            builder.append("\r\n\tAttempt to fall back to bcmail-jdk15-140 org.bouncycastle.cms.RecipientId");
            LOGGER.debug(builder.toString());
        }
    }
    if (retVal == null) {
        try {
            // fall back to bcmail-jdk15-140 interfaces
            loadClass = (Class<RecipientId>) getClass().getClassLoader().loadClass("org.bouncycastle.cms.RecipientId");
            retVal = loadClass.newInstance();
            retVal.setSerialNumber(decryptCert.getSerialNumber());
            retVal.setIssuer(decryptCert.getIssuerX500Principal().getEncoded());
        } catch (Throwable e) {
            LOGGER.error("Attempt to fall back to bcmail-jdk15-140 org.bouncycastle.cms.RecipientId failed.", e);
        }
    }
    return retVal;
}
Also used : RecipientId(org.bouncycastle.cms.RecipientId)

Example 5 with RecipientId

use of org.bouncycastle.cms.RecipientId in project pdfbox by apache.

the class PublicKeySecurityHandler method prepareForDecryption.

/**
 * Prepares everything to decrypt the document.
 *
 * @param encryption encryption dictionary, can be retrieved via
 * {@link PDDocument#getEncryption()}
 * @param documentIDArray document id which is returned via
 * {@link org.apache.pdfbox.cos.COSDocument#getDocumentID()} (not used by
 * this handler)
 * @param decryptionMaterial Information used to decrypt the document.
 *
 * @throws IOException If there is an error accessing data. If verbose mode
 * is enabled, the exception message will provide more details why the
 * match wasn't successful.
 */
@Override
public void prepareForDecryption(PDEncryption encryption, COSArray documentIDArray, DecryptionMaterial decryptionMaterial) throws IOException {
    if (!(decryptionMaterial instanceof PublicKeyDecryptionMaterial)) {
        throw new IOException("Provided decryption material is not compatible with the document");
    }
    setDecryptMetadata(encryption.isEncryptMetaData());
    if (encryption.getLength() != 0) {
        this.keyLength = encryption.getLength();
    }
    PublicKeyDecryptionMaterial material = (PublicKeyDecryptionMaterial) decryptionMaterial;
    try {
        boolean foundRecipient = false;
        X509Certificate certificate = material.getCertificate();
        X509CertificateHolder materialCert = null;
        if (certificate != null) {
            materialCert = new X509CertificateHolder(certificate.getEncoded());
        }
        // the decrypted content of the enveloped data that match
        // the certificate in the decryption material provided
        byte[] envelopedData = null;
        // the bytes of each recipient in the recipients array
        byte[][] recipientFieldsBytes = new byte[encryption.getRecipientsLength()][];
        int recipientFieldsLength = 0;
        int i = 0;
        StringBuilder extraInfo = new StringBuilder();
        for (; i < encryption.getRecipientsLength(); i++) {
            COSString recipientFieldString = encryption.getRecipientStringAt(i);
            byte[] recipientBytes = recipientFieldString.getBytes();
            CMSEnvelopedData data = new CMSEnvelopedData(recipientBytes);
            Collection<RecipientInformation> recipCertificatesIt = data.getRecipientInfos().getRecipients();
            int j = 0;
            for (RecipientInformation ri : recipCertificatesIt) {
                // Impl: if a matching certificate was previously found it is an error,
                // here we just don't care about it
                RecipientId rid = ri.getRID();
                if (!foundRecipient && rid.match(materialCert)) {
                    foundRecipient = true;
                    PrivateKey privateKey = (PrivateKey) material.getPrivateKey();
                    envelopedData = ri.getContent(new JceKeyTransEnvelopedRecipient(privateKey));
                    break;
                }
                j++;
                if (certificate != null) {
                    extraInfo.append('\n');
                    extraInfo.append(j);
                    extraInfo.append(": ");
                    if (rid instanceof KeyTransRecipientId) {
                        appendCertInfo(extraInfo, (KeyTransRecipientId) rid, certificate, materialCert);
                    }
                }
            }
            recipientFieldsBytes[i] = recipientBytes;
            recipientFieldsLength += recipientBytes.length;
        }
        if (!foundRecipient || envelopedData == null) {
            throw new IOException("The certificate matches none of " + i + " recipient entries" + extraInfo.toString());
        }
        if (envelopedData.length != 24) {
            throw new IOException("The enveloped data does not contain 24 bytes");
        }
        // now envelopedData contains:
        // - the 20 bytes seed
        // - the 4 bytes of permission for the current user
        byte[] accessBytes = new byte[4];
        System.arraycopy(envelopedData, 20, accessBytes, 0, 4);
        AccessPermission currentAccessPermission = new AccessPermission(accessBytes);
        currentAccessPermission.setReadOnly();
        setCurrentAccessPermission(currentAccessPermission);
        // what we will put in the SHA1 = the seed + each byte contained in the recipients array
        byte[] sha1Input = new byte[recipientFieldsLength + 20];
        // put the seed in the sha1 input
        System.arraycopy(envelopedData, 0, sha1Input, 0, 20);
        // put each bytes of the recipients array in the sha1 input
        int sha1InputOffset = 20;
        for (byte[] recipientFieldsByte : recipientFieldsBytes) {
            System.arraycopy(recipientFieldsByte, 0, sha1Input, sha1InputOffset, recipientFieldsByte.length);
            sha1InputOffset += recipientFieldsByte.length;
        }
        MessageDigest md = MessageDigests.getSHA1();
        byte[] mdResult = md.digest(sha1Input);
        // we have the encryption key ...
        encryptionKey = new byte[this.keyLength / 8];
        System.arraycopy(mdResult, 0, encryptionKey, 0, this.keyLength / 8);
    } catch (CMSException | KeyStoreException | CertificateEncodingException e) {
        throw new IOException(e);
    }
}
Also used : CMSEnvelopedData(org.bouncycastle.cms.CMSEnvelopedData) KeyTransRecipientId(org.bouncycastle.cms.KeyTransRecipientId) RecipientId(org.bouncycastle.cms.RecipientId) PrivateKey(java.security.PrivateKey) KeyTransRecipientId(org.bouncycastle.cms.KeyTransRecipientId) JceKeyTransEnvelopedRecipient(org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient) CertificateEncodingException(java.security.cert.CertificateEncodingException) IOException(java.io.IOException) KeyStoreException(java.security.KeyStoreException) X509Certificate(java.security.cert.X509Certificate) RecipientInformation(org.bouncycastle.cms.RecipientInformation) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) MessageDigest(java.security.MessageDigest) COSString(org.apache.pdfbox.cos.COSString) CMSException(org.bouncycastle.cms.CMSException)

Aggregations

RecipientId (org.bouncycastle.cms.RecipientId)5 PrivateKey (java.security.PrivateKey)3 RecipientInformationStore (org.bouncycastle.cms.RecipientInformationStore)3 SMIMEEnveloped (org.bouncycastle.mail.smime.SMIMEEnveloped)3 IOException (java.io.IOException)2 KeyStore (java.security.KeyStore)2 X509Certificate (java.security.cert.X509Certificate)2 MessagingException (javax.mail.MessagingException)2 MimeBodyPart (javax.mail.internet.MimeBodyPart)2 RecipientInformation (org.bouncycastle.cms.RecipientInformation)2 JceKeyTransEnvelopedRecipient (org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient)2 DirectRecipientInformation (org.nhindirect.stagent.cryptography.activekeyops.DirectRecipientInformation)2 ActionException (com.axway.ats.action.model.ActionException)1 MimePackage (com.axway.ats.action.objects.MimePackage)1 PublicAtsApi (com.axway.ats.common.PublicAtsApi)1 BASE64DecoderStream (com.sun.mail.util.BASE64DecoderStream)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 File (java.io.File)1 InputStream (java.io.InputStream)1 KeyStoreException (java.security.KeyStoreException)1