Esempio n. 1
0
  protected void decompress(@Nonnull final IMessage aMsg) throws DispositionException {
    try {
      if (aMsg.getPartnership().isDisableDecompress()) {
        s_aLogger.info(
            "Message claims to be compressed but decompression is disabled"
                + aMsg.getLoggingText());
      } else {
        if (s_aLogger.isDebugEnabled()) s_aLogger.debug("Decompressing a compressed AS2 message");

        final SMIMECompressed aCompressed = new SMIMECompressed(aMsg.getData());
        // decompression step MimeBodyPart
        final MimeBodyPart aDecompressedPart =
            SMIMEUtil.toMimeBodyPart(aCompressed.getContent(new ZlibExpanderProvider()));
        // Update the message object
        aMsg.setData(aDecompressedPart);
        // Remember that message was decompressed
        aMsg.setAttribute(AS2Message.ATTRIBUTE_RECEIVED_COMPRESSED, Boolean.TRUE.toString());
        s_aLogger.info("Successfully decompressed incoming AS2 message" + aMsg.getLoggingText());
      }
    } catch (final Exception ex) {
      s_aLogger.error("Error decompressing received message", ex);
      throw new DispositionException(
          DispositionType.createError("unexpected-processing-error"),
          AbstractActiveNetModule.DISP_DECOMPRESSION_ERROR,
          ex);
    }
  }
Esempio n. 2
0
  protected void decrypt(@Nonnull final IMessage aMsg) throws OpenAS2Exception {
    final ICertificateFactory aCertFactory = m_aReceiverModule.getSession().getCertificateFactory();
    final ICryptoHelper aCryptoHelper = AS2Helper.getCryptoHelper();

    try {
      final boolean bDisableDecrypt = aMsg.getPartnership().isDisableDecrypt();
      final boolean bMsgIsEncrypted = aCryptoHelper.isEncrypted(aMsg.getData());
      final boolean bForceDecrypt = aMsg.getPartnership().isForceDecrypt();
      if (bMsgIsEncrypted && bDisableDecrypt) {
        s_aLogger.info(
            "Message claims to be encrypted but decryption is disabled" + aMsg.getLoggingText());
      } else if (bMsgIsEncrypted || bForceDecrypt) {
        // Decrypt
        if (bForceDecrypt && !bMsgIsEncrypted)
          s_aLogger.info("Forced decrypting" + aMsg.getLoggingText());
        else if (s_aLogger.isDebugEnabled()) s_aLogger.debug("Decrypting" + aMsg.getLoggingText());

        final X509Certificate aReceiverCert =
            aCertFactory.getCertificate(aMsg, ECertificatePartnershipType.RECEIVER);
        final PrivateKey aReceiverKey = aCertFactory.getPrivateKey(aMsg, aReceiverCert);
        final MimeBodyPart aDecryptedData =
            aCryptoHelper.decrypt(aMsg.getData(), aReceiverCert, aReceiverKey, bForceDecrypt);
        aMsg.setData(aDecryptedData);
        // Remember that message was encrypted
        aMsg.setAttribute(AS2Message.ATTRIBUTE_RECEIVED_ENCRYPTED, Boolean.TRUE.toString());
        s_aLogger.info("Successfully decrypted incoming AS2 message" + aMsg.getLoggingText());
      }
    } catch (final Exception ex) {
      s_aLogger.error("Error decrypting " + aMsg.getLoggingText() + ": " + ex.getMessage());
      throw new DispositionException(
          DispositionType.createError("decryption-failed"),
          AbstractActiveNetModule.DISP_DECRYPTION_ERROR,
          ex);
    }
  }
Esempio n. 3
0
  protected void verify(@Nonnull final IMessage aMsg) throws OpenAS2Exception {
    final ICertificateFactory aCertFactory = m_aReceiverModule.getSession().getCertificateFactory();
    final ICryptoHelper aCryptoHelper = AS2Helper.getCryptoHelper();

    try {
      final boolean bDisableVerify = aMsg.getPartnership().isDisableVerify();
      final boolean bMsgIsSigned = aCryptoHelper.isSigned(aMsg.getData());
      final boolean bForceVerify = aMsg.getPartnership().isForceVerify();
      if (bMsgIsSigned && bDisableVerify) {
        s_aLogger.info(
            "Message claims to be signed but signature validation is disabled"
                + aMsg.getLoggingText());
      } else if (bMsgIsSigned || bForceVerify) {
        if (bForceVerify && !bMsgIsSigned)
          s_aLogger.info("Forced verify signature" + aMsg.getLoggingText());
        else if (s_aLogger.isDebugEnabled())
          s_aLogger.debug("Verifying signature" + aMsg.getLoggingText());

        final X509Certificate aSenderCert =
            aCertFactory.getCertificateOrNull(aMsg, ECertificatePartnershipType.SENDER);
        boolean bUseCertificateInBodyPart;
        final ETriState eUseCertificateInBodyPart =
            aMsg.getPartnership().getVerifyUseCertificateInBodyPart();
        if (eUseCertificateInBodyPart.isDefined()) {
          // Use per partnership
          bUseCertificateInBodyPart = eUseCertificateInBodyPart.getAsBooleanValue();
        } else {
          // Use global value
          bUseCertificateInBodyPart =
              m_aReceiverModule.getSession().isCryptoVerifyUseCertificateInBodyPart();
        }

        final MimeBodyPart aVerifiedData =
            aCryptoHelper.verify(
                aMsg.getData(), aSenderCert, bUseCertificateInBodyPart, bForceVerify);
        aMsg.setData(aVerifiedData);
        // Remember that message was signed and verified
        aMsg.setAttribute(AS2Message.ATTRIBUTE_RECEIVED_SIGNED, Boolean.TRUE.toString());
        s_aLogger.info(
            "Successfully verified signature of incoming AS2 message" + aMsg.getLoggingText());
      }
    } catch (final Exception ex) {
      s_aLogger.error(
          "Error verifying signature " + aMsg.getLoggingText() + ": " + ex.getMessage());
      throw new DispositionException(
          DispositionType.createError("integrity-check-failed"),
          AbstractActiveNetModule.DISP_VERIFY_SIGNATURE_FAILED,
          ex);
    }
  }
Esempio n. 4
0
  /**
   * This method can be used to handle an incoming HTTP message AFTER the headers where extracted.
   *
   * @param sClientInfo Client connection info
   * @param aMsgData The message body
   * @param aMsg The AS2 message that will be filled by this method
   * @param aResponseHandler The response handler which handles HTTP error messages as well as
   *     synchronous MDN.
   */
  public void handleIncomingMessage(
      @Nonnull final String sClientInfo,
      @Nonnull final byte[] aMsgData,
      @Nonnull final AS2Message aMsg,
      @Nonnull final IAS2HttpResponseHandler aResponseHandler) {
    // TODO store HTTP request, headers, and data to file in Received folder
    // -> use message-id for filename?
    try {
      final IAS2Session aSession = m_aReceiverModule.getSession();

      try {
        // Put received data in a MIME body part
        final ContentType aReceivedContentType =
            new ContentType(aMsg.getHeader(CAS2Header.HEADER_CONTENT_TYPE));
        final String sReceivedContentType = aReceivedContentType.toString();

        final MimeBodyPart aReceivedPart = new MimeBodyPart();
        aReceivedPart.setDataHandler(
            new DataHandler(new ByteArrayDataSource(aMsgData, sReceivedContentType, null)));

        // Header must be set AFTER the DataHandler!
        aReceivedPart.setHeader(CAS2Header.HEADER_CONTENT_TYPE, sReceivedContentType);
        aMsg.setData(aReceivedPart);
      } catch (final Exception ex) {
        throw new DispositionException(
            DispositionType.createError("unexpected-processing-error"),
            AbstractActiveNetModule.DISP_PARSING_MIME_FAILED,
            ex);
      }

      // Extract AS2 ID's from header, find the message's partnership and
      // update the message
      try {
        final String sAS2From = aMsg.getAS2From();
        aMsg.getPartnership().setSenderAS2ID(sAS2From);

        final String sAS2To = aMsg.getAS2To();
        aMsg.getPartnership().setReceiverAS2ID(sAS2To);

        // Fill all partnership attributes etc.
        aSession.getPartnershipFactory().updatePartnership(aMsg, false);
      } catch (final OpenAS2Exception ex) {
        throw new DispositionException(
            DispositionType.createError("authentication-failed"),
            AbstractActiveNetModule.DISP_PARTNERSHIP_NOT_FOUND,
            ex);
      }

      // Per RFC5402 compression is always before encryption but can be before
      // or after signing of message but only in one place
      final ICryptoHelper aCryptoHelper = AS2Helper.getCryptoHelper();
      boolean bIsDecompressed = false;

      // Decrypt and verify signature of the data, and attach data to the
      // message
      decrypt(aMsg);

      if (aCryptoHelper.isCompressed(aMsg.getContentType())) {
        if (s_aLogger.isTraceEnabled())
          s_aLogger.trace("Decompressing received message before checking signature...");
        decompress(aMsg);
        bIsDecompressed = true;
      }

      verify(aMsg);

      if (aCryptoHelper.isCompressed(aMsg.getContentType())) {
        // Per RFC5402 compression is always before encryption but can be before
        // or after signing of message but only in one place
        if (bIsDecompressed) {
          throw new DispositionException(
              DispositionType.createError("decompression-failed"),
              AbstractActiveNetModule.DISP_DECOMPRESSION_ERROR,
              new Exception(
                  "Message has already been decompressed. Per RFC5402 it cannot occur twice."));
        }

        if (s_aLogger.isTraceEnabled())
          if (aMsg.containsAttribute(AS2Message.ATTRIBUTE_RECEIVED_SIGNED))
            s_aLogger.trace("Decompressing received message after verifying signature...");
          else s_aLogger.trace("Decompressing received message after decryption...");
        decompress(aMsg);
        bIsDecompressed = true;
      }

      if (s_aLogger.isTraceEnabled())
        try {
          s_aLogger.trace(
              "SMIME Decrypted Content-Disposition: "
                  + aMsg.getContentDisposition()
                  + "\n      Content-Type received: "
                  + aMsg.getContentType()
                  + "\n      HEADERS after decryption: "
                  + aMsg.getData().getAllHeaders()
                  + "\n      Content-Disposition in MSG detData() MIMEPART after decryption: "
                  + aMsg.getData().getContentType());
        } catch (final MessagingException ex) {
          s_aLogger.error("Failed to trace message: " + aMsg, ex);
        }

      // Validate the received message before storing
      try {
        aSession
            .getMessageProcessor()
            .handle(IProcessorStorageModule.DO_VALIDATE_BEFORE_STORE, aMsg, null);
      } catch (final NoModuleException ex) {
        // No module installed - ignore
      } catch (final OpenAS2Exception ex) {
        throw new DispositionException(
            DispositionType.createError("unexpected-processing-error"),
            AbstractActiveNetModule.DISP_VALIDATION_FAILED
                + "\n"
                + StackTraceHelper.getStackAsString(ex),
            ex);
      }

      // Store the received message
      try {
        aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_STORE, aMsg, null);
      } catch (final NoModuleException ex) {
        // No module installed - ignore
      } catch (final OpenAS2Exception ex) {
        throw new DispositionException(
            DispositionType.createError("unexpected-processing-error"),
            AbstractActiveNetModule.DISP_STORAGE_FAILED + "\n" + ex.getMessage(),
            ex);
      }

      // Validate the received message after storing
      try {
        aSession
            .getMessageProcessor()
            .handle(IProcessorStorageModule.DO_VALIDATE_AFTER_STORE, aMsg, null);
      } catch (final NoModuleException ex) {
        // No module installed - ignore
      } catch (final OpenAS2Exception ex) {
        throw new DispositionException(
            DispositionType.createError("unexpected-processing-error"),
            AbstractActiveNetModule.DISP_VALIDATION_FAILED
                + "\n"
                + StackTraceHelper.getStackAsString(ex),
            ex);
      }

      try {
        if (aMsg.isRequestingMDN()) {
          // Transmit a success MDN if requested
          sendSyncMDN(
              sClientInfo,
              aResponseHandler,
              aMsg,
              DispositionType.createSuccess(),
              AbstractActiveNetModule.DISP_SUCCESS);
        } else {
          // Just send a HTTP OK
          HTTPHelper.sendSimpleHTTPResponse(aResponseHandler, HttpURLConnection.HTTP_OK);
          s_aLogger.info("sent HTTP OK " + sClientInfo + aMsg.getLoggingText());
        }
      } catch (final Exception ex) {
        throw new WrappedOpenAS2Exception(
            "Error creating and returning MDN, message was stilled processed", ex);
      }
    } catch (final DispositionException ex) {
      sendSyncMDN(sClientInfo, aResponseHandler, aMsg, ex.getDisposition(), ex.getText());
      m_aReceiverModule.handleError(aMsg, ex);
    } catch (final OpenAS2Exception ex) {
      m_aReceiverModule.handleError(aMsg, ex);
    }
  }