Search in sources :

Example 31 with NonBlockingByteArrayOutputStream

use of com.helger.commons.io.stream.NonBlockingByteArrayOutputStream in project as2-lib by phax.

the class AS2ReceiverHandler method sendMDN.

protected void sendMDN(@Nonnull final String sClientInfo, @Nonnull final IAS2HttpResponseHandler aResponseHandler, @Nonnull final AS2Message aMsg, @Nonnull final DispositionType aDisposition, @Nonnull final String sText, @Nonnull final ESuccess eSuccess) {
    final boolean bAllowErrorMDN = !aMsg.partnership().isBlockErrorMDN();
    if (eSuccess.isSuccess() || bAllowErrorMDN) {
        try {
            final IAS2Session aSession = m_aReceiverModule.getSession();
            final IMessageMDN aMdn = AS2Helper.createMDN(aSession, aMsg, aDisposition, sText);
            if (aMsg.isRequestingAsynchMDN()) {
                // if asyncMDN requested, close existing synchronous connection and
                // initiate separate MDN send
                final HttpHeaderMap aHeaders = new HttpHeaderMap();
                aHeaders.setContentLength(0);
                try (final NonBlockingByteArrayOutputStream aData = new NonBlockingByteArrayOutputStream()) {
                    // Empty data
                    // Ideally this would be HTTP 204 (no content)
                    aResponseHandler.sendHttpResponse(CHttp.HTTP_OK, aHeaders, aData);
                }
                if (LOGGER.isInfoEnabled())
                    LOGGER.info("Setup to send async MDN [" + aDisposition.getAsString() + "] " + sClientInfo + aMsg.getLoggingText());
                // trigger explicit async sending
                aSession.getMessageProcessor().handle(IProcessorSenderModule.DO_SEND_ASYNC_MDN, aMsg, null);
            } else {
                // otherwise, send sync MDN back on same connection
                if (LOGGER.isInfoEnabled())
                    LOGGER.info("Sending back sync MDN [" + aDisposition.getAsString() + "] " + sClientInfo + aMsg.getLoggingText());
                // Get data and therefore content length for sync MDN
                try (final NonBlockingByteArrayOutputStream aData = new NonBlockingByteArrayOutputStream()) {
                    final MimeBodyPart aPart = aMdn.getData();
                    StreamHelper.copyInputStreamToOutputStream(aPart.getInputStream(), aData);
                    aMdn.headers().setContentLength(aData.size());
                    // start HTTP response
                    aResponseHandler.sendHttpResponse(CHttp.HTTP_OK, aMdn.headers(), aData);
                }
                // Save sent MDN for later examination
                try {
                    aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_STOREMDN, aMsg, null);
                } catch (final AS2ComponentNotFoundException | AS2NoModuleException ex) {
                // No message processor found
                // or No module found in message processor
                }
                if (LOGGER.isInfoEnabled())
                    LOGGER.info("sent MDN [" + aDisposition.getAsString() + "] " + sClientInfo + aMsg.getLoggingText());
            }
        } catch (final Exception ex) {
            WrappedAS2Exception.wrap(ex).terminate(aMsg);
        }
    }
}
Also used : HttpHeaderMap(com.helger.commons.http.HttpHeaderMap) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) NonBlockingByteArrayOutputStream(com.helger.commons.io.stream.NonBlockingByteArrayOutputStream) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) IMessageMDN(com.helger.as2lib.message.IMessageMDN) MimeBodyPart(javax.mail.internet.MimeBodyPart) MessagingException(javax.mail.MessagingException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2DispositionException(com.helger.as2lib.disposition.AS2DispositionException) AS2ProcessorException(com.helger.as2lib.processor.AS2ProcessorException) CMSException(org.bouncycastle.cms.CMSException) AS2Exception(com.helger.as2lib.exception.AS2Exception) WrappedAS2Exception(com.helger.as2lib.exception.WrappedAS2Exception) IOException(java.io.IOException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) IAS2Session(com.helger.as2lib.session.IAS2Session)

Example 32 with NonBlockingByteArrayOutputStream

use of com.helger.commons.io.stream.NonBlockingByteArrayOutputStream in project as2-lib by phax.

the class BCCryptoHelper method decrypt.

@Nonnull
public MimeBodyPart decrypt(@Nonnull final MimeBodyPart aPart, @Nonnull final X509Certificate aX509Cert, @Nonnull final PrivateKey aPrivateKey, final boolean bForceDecrypt, @Nonnull final AS2ResourceHelper aResHelper) throws GeneralSecurityException, MessagingException, CMSException, SMIMEException, IOException {
    ValueEnforcer.notNull(aPart, "MimeBodyPart");
    ValueEnforcer.notNull(aX509Cert, "X509Cert");
    ValueEnforcer.notNull(aPrivateKey, "PrivateKey");
    ValueEnforcer.notNull(aResHelper, "ResHelper");
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("BCCryptoHelper.decrypt; X509 subject=" + aX509Cert.getSubjectX500Principal().getName() + "; forceDecrypt=" + bForceDecrypt);
    // Make sure the data is encrypted
    if (!bForceDecrypt && !isEncrypted(aPart))
        throw new GeneralSecurityException("Content-Type '" + aPart.getContentType() + "' indicates data isn't encrypted");
    // Get the recipient object for decryption
    final RecipientId aRecipientID = new JceKeyTransRecipientId(aX509Cert);
    // Parse the MIME body into an SMIME envelope object
    RecipientInformation aRecipient = null;
    try {
        final SMIMEEnvelopedParser aEnvelope = new SMIMEEnvelopedParser(aPart);
        aRecipient = aEnvelope.getRecipientInfos().get(aRecipientID);
    } catch (final Exception ex) {
        LOGGER.error("Error retrieving RecipientInformation", ex);
    }
    if (aRecipient == null)
        throw new GeneralSecurityException("Certificate does not match part signature");
    // try to decrypt the data
    // Custom file: see #103
    final FileBackedMimeBodyPart aDecryptedDataBodyPart = SMIMEUtil.toMimeBodyPart(aRecipient.getContentStream(new JceKeyTransEnvelopedRecipient(aPrivateKey).setProvider(m_sSecurityProviderName)), aResHelper.createTempFile());
    if (DUMP_DECRYPTED_DIR_PATH != null) {
        // dump decrypted
        try (final NonBlockingByteArrayOutputStream aBAOS = new NonBlockingByteArrayOutputStream(aDecryptedDataBodyPart.getSize())) {
            aDecryptedDataBodyPart.writeTo(aBAOS);
            _dumpDecrypted(aBAOS.toByteArray());
        }
    }
    return aDecryptedDataBodyPart;
}
Also used : RecipientInformation(org.bouncycastle.cms.RecipientInformation) FileBackedMimeBodyPart(org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart) JceKeyTransRecipientId(org.bouncycastle.cms.jcajce.JceKeyTransRecipientId) RecipientId(org.bouncycastle.cms.RecipientId) SMIMEEnvelopedParser(org.bouncycastle.mail.smime.SMIMEEnvelopedParser) GeneralSecurityException(java.security.GeneralSecurityException) JceKeyTransRecipientId(org.bouncycastle.cms.jcajce.JceKeyTransRecipientId) NonBlockingByteArrayOutputStream(com.helger.commons.io.stream.NonBlockingByteArrayOutputStream) JceKeyTransEnvelopedRecipient(org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) MessagingException(javax.mail.MessagingException) GeneralSecurityException(java.security.GeneralSecurityException) SignatureException(java.security.SignatureException) CMSException(org.bouncycastle.cms.CMSException) AS2Exception(com.helger.as2lib.exception.AS2Exception) IOException(java.io.IOException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) Nonnull(javax.annotation.Nonnull)

Example 33 with NonBlockingByteArrayOutputStream

use of com.helger.commons.io.stream.NonBlockingByteArrayOutputStream in project as2-lib by phax.

the class MimeBodyPartFuncTest method testWriteContentTransferEncoding8Bit.

@Test
public void testWriteContentTransferEncoding8Bit() throws MessagingException, IOException {
    final String sTestMsg = "Test message\nLine 2\n\nLine 4\nEOF";
    // Build message content
    final MimeBodyPart aPart = new MimeBodyPart();
    aPart.setText(sTestMsg, StandardCharsets.ISO_8859_1.name());
    aPart.addHeader("x-custom", "junit");
    aPart.addHeader(CHttpHeader.CONTENT_TYPE, "text/plain");
    aPart.addHeader(CHttpHeader.CONTENT_TRANSFER_ENCODING, EContentTransferEncoding._8BIT.getID());
    aPart.addHeader(CHttpHeader.CONTENT_LENGTH, Integer.toString(sTestMsg.length()));
    final NonBlockingByteArrayOutputStream aBAOS = new NonBlockingByteArrayOutputStream();
    aPart.writeTo(aBAOS);
    StreamHelper.close(aBAOS);
    final String sMsgPart = aBAOS.getAsString(StandardCharsets.ISO_8859_1);
    if (false)
        LOGGER.info(sMsgPart);
    assertTrue(sMsgPart, sMsgPart.contains("Content-Type: text/plain"));
    assertTrue(sMsgPart, sMsgPart.contains("Content-Transfer-Encoding: 8bit"));
    assertTrue(sMsgPart, sMsgPart.contains("x-custom: junit"));
    assertTrue(sMsgPart, sMsgPart.contains(sTestMsg));
}
Also used : NonBlockingByteArrayOutputStream(com.helger.commons.io.stream.NonBlockingByteArrayOutputStream) MimeBodyPart(javax.mail.internet.MimeBodyPart) Test(org.junit.Test)

Example 34 with NonBlockingByteArrayOutputStream

use of com.helger.commons.io.stream.NonBlockingByteArrayOutputStream in project as2-lib by phax.

the class MimeBodyPartFuncTest method testReadContentTransferEncodingBase64.

@Test
public void testReadContentTransferEncodingBase64() throws MessagingException, IOException {
    final String sHTTP = "Content-Type: text/plain" + CHttp.EOL + "Content-Transfer-Encoding: base64" + CHttp.EOL + "x-custom: junit" + CHttp.EOL + "Content-Length: 44" + CHttp.EOL + CHttp.EOL + "VGVzdCBtZXNzYWdlCkxpbmUgMgoKTGluZSA0CkVPRg==" + CHttp.EOL;
    InputStream aIS = new StringInputStream(sHTTP, StandardCharsets.ISO_8859_1);
    // Parse all HTTP headers from stream
    final InternetHeaders aHeaders = new InternetHeaders(aIS);
    final String sCTE = aHeaders.getHeader(CHttpHeader.CONTENT_TRANSFER_ENCODING)[0];
    if (StringHelper.hasText(sCTE))
        aIS = AS2IOHelper.getContentTransferEncodingAwareInputStream(aIS, sCTE);
    // Read the payload
    final byte[] aData = StreamHelper.getAllBytes(aIS);
    // Extract content type
    final String sReceivedContentType = AS2HttpHelper.getCleanContentType(aHeaders.getHeader(CHttpHeader.CONTENT_TYPE)[0]);
    final MimeBodyPart aReceivedPart = new MimeBodyPart();
    aReceivedPart.setDataHandler(new ByteArrayDataSource(aData, sReceivedContentType, null).getAsDataHandler());
    aReceivedPart.setHeader("x-received", "true");
    final NonBlockingByteArrayOutputStream aBAOS = new NonBlockingByteArrayOutputStream();
    aReceivedPart.writeTo(aBAOS);
    StreamHelper.close(aBAOS);
    final String sMsgPart = aBAOS.getAsString(StandardCharsets.ISO_8859_1);
    if (true)
        LOGGER.info(sMsgPart);
}
Also used : StringInputStream(com.helger.commons.io.stream.StringInputStream) InternetHeaders(javax.mail.internet.InternetHeaders) StringInputStream(com.helger.commons.io.stream.StringInputStream) InputStream(java.io.InputStream) NonBlockingByteArrayOutputStream(com.helger.commons.io.stream.NonBlockingByteArrayOutputStream) MimeBodyPart(javax.mail.internet.MimeBodyPart) ByteArrayDataSource(com.helger.mail.datasource.ByteArrayDataSource) Test(org.junit.Test)

Example 35 with NonBlockingByteArrayOutputStream

use of com.helger.commons.io.stream.NonBlockingByteArrayOutputStream in project as2-lib by phax.

the class AS2SenderModule method receiveSyncMDN.

/**
 * @param aMsg
 *        AS2Message
 * @param aHttpClient
 *        URLConnection
 * @param aOriginalMIC
 *        mic value from original msg
 * @param aIncomingDumper
 *        Incoming dumper. May be <code>null</code>.
 * @param aResHelper
 *        Resource helper
 * @throws AS2Exception
 *         in case of an error
 * @throws IOException
 *         in case of an IO error
 */
protected void receiveSyncMDN(@Nonnull final AS2Message aMsg, @Nonnull final AS2HttpClient aHttpClient, @Nonnull final MIC aOriginalMIC, @Nullable final IHTTPIncomingDumper aIncomingDumper, @Nonnull final AS2ResourceHelper aResHelper) throws AS2Exception, IOException {
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("Receiving synchronous MDN for message" + aMsg.getLoggingText());
    try {
        // Create a MessageMDN and copy HTTP headers
        final IMessageMDN aMDN = new AS2MessageMDN(aMsg);
        // Bug in ph-commons 9.1.3 in addAllHeaders!
        aMDN.headers().addAllHeaders(aHttpClient.getResponseHeaderFields());
        // Receive the MDN data
        final InputStream aConnIS = aHttpClient.getInputStream();
        final NonBlockingByteArrayOutputStream aMDNStream = new NonBlockingByteArrayOutputStream();
        // Retrieve the whole MDN content
        StreamHelper.copyByteStream().from(aConnIS).closeFrom(true).to(aMDNStream).closeTo(true).limit(StringParser.parseLong(aMDN.getHeader(CHttpHeader.CONTENT_LENGTH), -1)).build();
        // Dump collected message
        if (aIncomingDumper != null)
            aIncomingDumper.dumpIncomingRequest(aMDN.headers().getAllHeaderLines(true), aMDNStream.getBufferOrCopy(), aMDN);
        if (LOGGER.isTraceEnabled()) {
            // Debug print the whole MDN stream
            LOGGER.trace("Retrieved MDN stream data:\n" + aMDNStream.getAsString(StandardCharsets.ISO_8859_1));
        }
        final MimeBodyPart aPart = new MimeBodyPart(AS2HttpHelper.getAsInternetHeaders(aMDN.headers()), aMDNStream.getBufferOrCopy());
        aMDN.setData(aPart);
        // get the MDN partnership info
        aMDN.partnership().setSenderAS2ID(aMDN.getHeader(CHttpHeader.AS2_FROM));
        aMDN.partnership().setReceiverAS2ID(aMDN.getHeader(CHttpHeader.AS2_TO));
        // Set the appropriate key store aliases
        aMDN.partnership().setSenderX509Alias(aMsg.partnership().getReceiverX509Alias());
        aMDN.partnership().setReceiverX509Alias(aMsg.partnership().getSenderX509Alias());
        // Update the partnership
        getSession().getPartnershipFactory().updatePartnership(aMDN, false);
        final ICertificateFactory aCertFactory = getSession().getCertificateFactory();
        final X509Certificate aSenderCert = aCertFactory.getCertificate(aMDN, ECertificatePartnershipType.SENDER);
        boolean bUseCertificateInBodyPart;
        final ETriState eUseCertificateInBodyPart = aMsg.partnership().getVerifyUseCertificateInBodyPart();
        if (eUseCertificateInBodyPart.isDefined()) {
            // Use per partnership
            bUseCertificateInBodyPart = eUseCertificateInBodyPart.getAsBooleanValue();
        } else {
            // Use global value
            bUseCertificateInBodyPart = getSession().isCryptoVerifyUseCertificateInBodyPart();
        }
        AS2Helper.parseMDN(aMsg, aSenderCert, bUseCertificateInBodyPart, m_aVerificationCertificateConsumer, aResHelper);
        try {
            getSession().getMessageProcessor().handle(IProcessorStorageModule.DO_STOREMDN, aMsg, null);
        } catch (final AS2ComponentNotFoundException | AS2NoModuleException ex) {
        // No message processor found
        // Or no module found in message processor
        }
        final String sDisposition = aMDN.attrs().getAsString(AS2MessageMDN.MDNA_DISPOSITION);
        if (LOGGER.isInfoEnabled())
            LOGGER.info("Received synchronous AS2 MDN [" + sDisposition + "]" + aMsg.getLoggingText());
        // Asynch MDN 2007-03-12
        // Verify if the original mic is equal to the mic in returned MDN
        final String sReturnMIC = aMDN.attrs().getAsString(AS2MessageMDN.MDNA_MIC);
        final MIC aReturnMIC = MIC.parse(sReturnMIC);
        // Catch ReturnMIC == null in case the attribute is simply missing
        final boolean bMICMatch = aOriginalMIC != null && aReturnMIC != null && aReturnMIC.equals(aOriginalMIC);
        if (bMICMatch) {
            // MIC was matched - all good
            m_aMICMatchingHandler.onMICMatch(aMsg, sReturnMIC);
        } else {
            // file was sent completely but the returned mic was not matched,
            m_aMICMatchingHandler.onMICMismatch(aMsg, aOriginalMIC == null ? null : aOriginalMIC.getAsAS2String(), sReturnMIC);
        }
        if (m_aIncomingMDNCallback != null)
            m_aIncomingMDNCallback.onIncomingMDN(true, aMDN, aMDN.getHeader(CHttpHeader.AS2_FROM), aMDN.getHeader(CHttpHeader.AS2_TO), sDisposition, aMDN.attrs().getAsString(AS2MessageMDN.MDNA_MIC), aMDN.attrs().getAsString(AS2MessageMDN.MDNA_ORIG_MESSAGEID), aMDN.attrs().getAsBoolean(AS2Message.ATTRIBUTE_RECEIVED_SIGNED, false), bMICMatch);
        DispositionType.createFromString(sDisposition).validate(aMsg, aMDN.getText());
    } catch (final IOException ex) {
        throw ex;
    } catch (final Exception ex) {
        throw WrappedAS2Exception.wrap(ex).setSourceMsg(aMsg);
    }
}
Also used : AS2MessageMDN(com.helger.as2lib.message.AS2MessageMDN) ETriState(com.helger.commons.state.ETriState) InputStream(java.io.InputStream) MIC(com.helger.as2lib.crypto.MIC) NonBlockingByteArrayOutputStream(com.helger.commons.io.stream.NonBlockingByteArrayOutputStream) ICertificateFactory(com.helger.as2lib.cert.ICertificateFactory) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) MessagingException(javax.mail.MessagingException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2DispositionException(com.helger.as2lib.disposition.AS2DispositionException) AS2Exception(com.helger.as2lib.exception.AS2Exception) WrappedAS2Exception(com.helger.as2lib.exception.WrappedAS2Exception) IOException(java.io.IOException) AS2InvalidParameterException(com.helger.as2lib.params.AS2InvalidParameterException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) AS2NoModuleException(com.helger.as2lib.processor.AS2NoModuleException) AS2ComponentNotFoundException(com.helger.as2lib.session.AS2ComponentNotFoundException) IMessageMDN(com.helger.as2lib.message.IMessageMDN) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Aggregations

NonBlockingByteArrayOutputStream (com.helger.commons.io.stream.NonBlockingByteArrayOutputStream)55 Test (org.junit.Test)30 IOException (java.io.IOException)12 MimeBodyPart (javax.mail.internet.MimeBodyPart)12 NonBlockingByteArrayInputStream (com.helger.commons.io.stream.NonBlockingByteArrayInputStream)8 InputStream (java.io.InputStream)7 Nonnull (javax.annotation.Nonnull)7 MessagingException (javax.mail.MessagingException)7 IMicroDocument (com.helger.xml.microdom.IMicroDocument)4 AS2Exception (com.helger.as2lib.exception.AS2Exception)3 IMessageMDN (com.helger.as2lib.message.IMessageMDN)3 CommonsArrayList (com.helger.commons.collection.impl.CommonsArrayList)3 ByteArrayOutputStreamProvider (com.helger.commons.io.streamprovider.ByteArrayOutputStreamProvider)3 MockMarshallerExternal (com.helger.jaxb.mock.MockMarshallerExternal)3 MockJAXBArchive (com.helger.jaxb.mock.external.MockJAXBArchive)3 XMLWriterSettings (com.helger.xml.serialize.write.XMLWriterSettings)3 Nullable (javax.annotation.Nullable)3 SMIMEException (org.bouncycastle.mail.smime.SMIMEException)3 AS2DispositionException (com.helger.as2lib.disposition.AS2DispositionException)2 WrappedAS2Exception (com.helger.as2lib.exception.WrappedAS2Exception)2