public static void startSMimeDecryption (final String encryptedPath, String decryptedPath) { logger.info("*** Start of sMIME decryption ***"); //$NON-NLS-1$ Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); try { logger.info("Encrypted message: [" + encryptedPath + "]"); //$NON-NLS-1$ //$NON-NLS-2$ File messageFile = new File(encryptedPath); String fileExtension = getFileExtension(messageFile); if (fileExtension != null) { MimeMessage m = null; if (fileExtension.toUpperCase().equals("EML")) { //$NON-NLS-1$ try (FileInputStream streamIn = new FileInputStream(encryptedPath);) { logger.info("Created FileInputStream."); //$NON-NLS-1$ m = new MimeMessage(session, streamIn); logger.info("Created MimeMessage."); //$NON-NLS-1$ } catch (IOException e) { logger.error("Error while trying to read in message via stream. " + e.getMessage()); return; } } else if (fileExtension.toUpperCase().equals("MSG")) { //$NON-NLS-1$ m = createMimeMessageFromMsg(session, messageFile); logger.info("Created MimeMessage."); //$NON-NLS-1$ } else { throw new InvalidFileException("Not a supported file type (extension). Only '*.eml' and '*.msg' are accepted."); //$NON-NLS-1$ } if ((m.getFileName() != null) && (m.getFileName().toUpperCase().equals("SMIME.P7M") || Pattern.compile("^\\s*application\\/(x-)?pkcs7-mime.*$", Pattern.DOTALL).matcher(m.getContentType()).matches())) { //$NON-NLS-1$ //$NON-NLS-2$ m = decryptMessage(m); logger.info("Saving decrypted message to file..."); //$NON-NLS-1$ if (decryptedPath == null) { String tempPath = messageFile.getAbsolutePath().substring(0, messageFile.getAbsolutePath().lastIndexOf(File.separator)); decryptedPath = tempPath + File.separator + FilenameUtils.removeExtension(messageFile.getName()) + "_decrypted.eml"; //$NON-NLS-1$ } try (OutputStream str = Files.newOutputStream(Paths.get(decryptedPath))) { m.writeTo(str); } catch (IOException e) { logger.error("Failed to write to output stream. " + e.getMessage()); //$NON-NLS-1$ return; } logger.info("Decrypted message: [" + decryptedPath + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } else { throw new NotEncryptedMessageException("Not an encrypted message. Breaking up decryption."); //$NON-NLS-1$ } } else { throw new InvalidFileException("No file extension found."); //$NON-NLS-1$ } } catch (MessagingException | UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException | CMSException | InvalidFileException | InvalidMessageException e) { logger.error("Failed to read message. " + e.getMessage()); //$NON-NLS-1$ } catch (NotEncryptedMessageException e) { logger.error(e.getMessage()); System.exit(RETURNCODE_NODECRYPTION); } logger.info("*** End of sMIME decryption ***"); //$NON-NLS-1$ } private static MimeMessage createMimeMessageFromMsg (final Session session, final File messageFile) { MimeMessage mimeMsg = null; if (messageFile != null) { MAPIMessage mapiMsg = null; logger.info("Converting .msg to MimeMessage."); //$NON-NLS-1$ try (NPOIFSFileSystem npoi = new NPOIFSFileSystem(messageFile)) { logger.info("Created NPOIFSFileSystem."); //$NON-NLS-1$ mapiMsg = new MAPIMessage(npoi); logger.info("Created MAPIMessage."); //$NON-NLS-1$ mimeMsg = new MimeMessage(session); logger.info("Creating MimeMessage..."); //$NON-NLS-1$ // Header übertragen try { for (String current : mapiMsg.getHeaders()) { try { mimeMsg.addHeaderLine(current); } catch (MessagingException e) { logger.error("Could not add header line to MimeMessage. " + e.getMessage()); //$NON-NLS-1$ } } logger.info("Added header to MimeMessage."); //$NON-NLS-1$ } catch (ChunkNotFoundException e) { logger.error("Could not retrieve header. " + e.getMessage()); //$NON-NLS-1$ } // "Attachment" übertragen for (AttachmentChunks current : mapiMsg.getAttachmentFiles()) { try { ByteArrayDataSource ds = new ByteArrayDataSource(current.getEmbeddedAttachmentObject(), "application/pkcs7-mime"); //$NON-NLS-1$ DataHandler dh = new DataHandler(ds); mimeMsg.setDataHandler(dh); logger.info("Added attachment to MimeMessage."); //$NON-NLS-1$ } catch (MessagingException e) { logger.error("Could not transfer attachment into MimeMessage. " + e.getMessage()); //$NON-NLS-1$ } } } catch (IOException e) { logger.error("Error while trying to build MimeMessage. " + e.getMessage()); //$NON-NLS-1$ mimeMsg = null; } } return mimeMsg; } private static MimeMessage decryptMessage(final MimeMessage encrypted) throws MessagingException, CMSException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, InvalidMessageException { if (encrypted != null) { logger.info("Starting decrypting message..."); //$NON-NLS-1$ KeyStore keystore = getKeyStore(); SMIMEEnveloped message = new SMIMEEnveloped(encrypted); RecipientInformationStore recinfos = message.getRecipientInfos(); Enumeration aliases = keystore.aliases(); RecipientInformation recid = null; String alias = null; logger.info("Decrypting message..."); //$NON-NLS-1$ while ((recid == null) && aliases.hasMoreElements()) { alias = aliases.nextElement(); if (keystore.isKeyEntry(alias)) { Certificate cert = keystore.getCertificate(alias); recid = recinfos.get(new JceKeyTransRecipientId((X509Certificate) cert)); } } if (recid == null) { throw new RuntimeException("No decryption key found"); //$NON-NLS-1$ } JceKeyTransEnvelopedRecipient recipient = new JceKeyTransEnvelopedRecipient((PrivateKey) keystore.getKey(alias, "changeit".toCharArray())); //$NON-NLS-1$ byte[] content = recid.getContent(recipient); logger.info("Setting MimeMessage properties."); //$NON-NLS-1$ MimeMessage decrypted = new MimeMessage(Session.getDefaultInstance(System.getProperties()), new ByteArrayInputStream(content)); Enumeration
headers = encrypted.getAllHeaders(); while (headers.hasMoreElements()) { Header h = headers.nextElement(); if (decrypted.getHeader(h.getName()) == null) { decrypted.addHeader(h.getName(), h.getValue()); } } decrypted.saveChanges(); logger.info("Decrypted message."); //$NON-NLS-1$ return decrypted; } else { throw new InvalidMessageException("Encrypted MimeMessage is null."); //$NON-NLS-1$ } }