Search in sources :

Example 16 with AS4ResourceHelper

use of com.helger.phase4.util.AS4ResourceHelper in project phase4 by phax.

the class MainVerifySignature method _verifyAndDecrypt.

@Nonnull
private static ESuccess _verifyAndDecrypt(@Nonnull final IAS4CryptoFactory aCryptoFactory, @Nonnull final Document aSOAPDoc, @Nonnull final Locale aLocale, @Nonnull final AS4ResourceHelper aResHelper, @Nonnull final ICommonsList<WSS4JAttachment> aAttachments, @Nonnull final ErrorList aErrorList, @Nonnull final Supplier<WSSConfig> aWSSConfigSupplier) {
    // Signing verification and Decryption
    try {
        // Convert to WSS4J attachments
        final Phase4KeyStoreCallbackHandler aKeyStoreCallback = new Phase4KeyStoreCallbackHandler(aCryptoFactory);
        final WSS4JAttachmentCallbackHandler aAttachmentCallbackHandler = new WSS4JAttachmentCallbackHandler(aAttachments, aResHelper);
        // Resolve the WSS config here to ensure the context matches
        final WSSConfig aWSSConfig = aWSSConfigSupplier.get();
        // Configure RequestData needed for the check / decrypt process!
        final RequestData aRequestData = new RequestData();
        aRequestData.setCallbackHandler(aKeyStoreCallback);
        if (aAttachments.isNotEmpty())
            aRequestData.setAttachmentCallbackHandler(aAttachmentCallbackHandler);
        aRequestData.setSigVerCrypto(aCryptoFactory.getCrypto());
        aRequestData.setDecCrypto(aCryptoFactory.getCrypto());
        aRequestData.setWssConfig(aWSSConfig);
        // Upon success, the SOAP document contains the decrypted content
        // afterwards!
        final WSSecurityEngine aSecurityEngine = new WSSecurityEngine();
        aSecurityEngine.setWssConfig(aWSSConfig);
        final WSHandlerResult aHdlRes = aSecurityEngine.processSecurityHeader(aSOAPDoc, aRequestData);
        final List<WSSecurityEngineResult> aResults = aHdlRes.getResults();
        // Collect all unique used certificates
        final ICommonsSet<X509Certificate> aCertSet = new CommonsHashSet<>();
        // Preferred certificate from BinarySecurityToken
        X509Certificate aPreferredCert = null;
        int nWSS4JSecurityActions = 0;
        for (final WSSecurityEngineResult aResult : aResults) {
            if (LOGGER.isDebugEnabled())
                LOGGER.debug("WSSecurityEngineResult: " + aResult);
            final Integer aAction = (Integer) aResult.get(WSSecurityEngineResult.TAG_ACTION);
            final int nAction = aAction != null ? aAction.intValue() : 0;
            nWSS4JSecurityActions |= nAction;
            final X509Certificate aCert = (X509Certificate) aResult.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
            if (aCert != null) {
                aCertSet.add(aCert);
                if (nAction == WSConstants.BST && aPreferredCert == null)
                    aPreferredCert = aCert;
            }
        }
        // this determines if a signature check or a decryption happened
        final X509Certificate aUsedCert;
        if (aCertSet.size() > 1) {
            if (aPreferredCert == null) {
                LOGGER.warn("Found " + aCertSet.size() + " different certificates in message. Using the first one.");
                if (LOGGER.isDebugEnabled())
                    LOGGER.debug("All gathered certificates: " + aCertSet);
                aUsedCert = aCertSet.getAtIndex(0);
            } else
                aUsedCert = aPreferredCert;
        } else if (aCertSet.size() == 1)
            aUsedCert = aCertSet.getAtIndex(0);
        else
            aUsedCert = null;
        // Remember in State
        // Decrypting the Attachments
        final ICommonsList<WSS4JAttachment> aResponseAttachments = aAttachmentCallbackHandler.getAllResponseAttachments();
        for (final WSS4JAttachment aResponseAttachment : aResponseAttachments) {
            // Always copy to a temporary file, so that decrypted content can be
            // read more than once. By default the stream can only be read once
            // Not nice, but working :)
            final File aTempFile = aResHelper.createTempFile();
            StreamHelper.copyInputStreamToOutputStreamAndCloseOS(aResponseAttachment.getSourceStream(), FileHelper.getBufferedOutputStream(aTempFile));
            aResponseAttachment.setSourceStreamProvider(HasInputStream.multiple(() -> FileHelper.getBufferedInputStream(aTempFile)));
        }
        // Remember in State
        return ESuccess.SUCCESS;
    } catch (final IndexOutOfBoundsException | IllegalStateException | WSSecurityException ex) {
        // Decryption or Signature check failed
        LOGGER.error("Error processing the WSSSecurity Header", ex);
        // TODO we need a way to distinct
        // signature and decrypt WSSecurityException provides no such thing
        aErrorList.add(EEbmsError.EBMS_FAILED_DECRYPTION.getAsError(aLocale));
        return ESuccess.FAILURE;
    } catch (final IOException ex) {
        // Decryption or Signature check failed
        LOGGER.error("IO error processing the WSSSecurity Header", ex);
        aErrorList.add(EEbmsError.EBMS_OTHER.getAsError(aLocale));
        return ESuccess.FAILURE;
    }
}
Also used : WSS4JAttachmentCallbackHandler(com.helger.phase4.attachment.WSS4JAttachmentCallbackHandler) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) IOException(java.io.IOException) WSHandlerResult(org.apache.wss4j.dom.handler.WSHandlerResult) WSSecurityEngineResult(org.apache.wss4j.dom.engine.WSSecurityEngineResult) X509Certificate(java.security.cert.X509Certificate) WSSConfig(org.apache.wss4j.dom.engine.WSSConfig) RequestData(org.apache.wss4j.dom.handler.RequestData) WSSecurityEngine(org.apache.wss4j.dom.engine.WSSecurityEngine) Phase4KeyStoreCallbackHandler(com.helger.phase4.servlet.soap.Phase4KeyStoreCallbackHandler) CommonsHashSet(com.helger.commons.collection.impl.CommonsHashSet) File(java.io.File) WSS4JAttachment(com.helger.phase4.attachment.WSS4JAttachment) Nonnull(javax.annotation.Nonnull)

Example 17 with AS4ResourceHelper

use of com.helger.phase4.util.AS4ResourceHelper in project phase4 by phax.

the class MainVerifySignature method main.

public static void main(final String[] args) {
    WebScopeManager.onGlobalBegin(MockServletContext.create());
    try (AS4ResourceHelper aResHelper = new AS4ResourceHelper()) {
        final byte[] aBytes = StreamHelper.getAllBytes(FileHelper.getInputStream(new File("src/test/resources/verify/dataport1-mustunderstand.as4in")));
        int nHttpEnd = -1;
        boolean bLastWasCR = false;
        for (int i = 0; i < aBytes.length; ++i) {
            final byte b = aBytes[i];
            if (b == '\n') {
                if (bLastWasCR) {
                    nHttpEnd = i + 1;
                    break;
                }
                bLastWasCR = true;
            } else {
                if (b != '\r')
                    bLastWasCR = false;
            }
        }
        LOGGER.info("Now at byte " + nHttpEnd);
        final Document aSOAPDoc = DOMReader.readXMLDOM(aBytes, nHttpEnd, aBytes.length - nHttpEnd);
        if (aSOAPDoc == null)
            throw new IllegalStateException();
        final ErrorList aErrorList = new ErrorList();
        _verifyAndDecrypt(AS4CryptoFactoryProperties.getDefaultInstance(), aSOAPDoc, Locale.US, aResHelper, new CommonsArrayList<>(), aErrorList, WSSConfigManager.getInstance()::createWSSConfig);
    }
    WebScopeManager.onGlobalEnd();
}
Also used : ErrorList(com.helger.commons.error.list.ErrorList) Document(org.w3c.dom.Document) AS4ResourceHelper(com.helger.phase4.util.AS4ResourceHelper) File(java.io.File)

Example 18 with AS4ResourceHelper

use of com.helger.phase4.util.AS4ResourceHelper in project phase4 by phax.

the class DropFolderUserMessage method _send.

private static void _send(@Nonnull final IAS4CryptoFactory aCF, final Path aSendFile, final Path aIncomingDir) {
    final StopWatch aSW = StopWatch.createdStarted();
    boolean bSuccess = false;
    LOGGER.info("Trying to send " + aSendFile.toString());
    try (final AS4ResourceHelper aResHelper = new AS4ResourceHelper()) {
        // Read generic SBD
        final StandardBusinessDocument aSBD = SBDHReader.standardBusinessDocument().read(Files.newInputStream(aSendFile));
        if (aSBD == null) {
            LOGGER.error("Failed to read " + aSendFile.toString() + " as SBDH document!");
        } else {
            // Extract Peppol specific data
            final PeppolSBDHDocument aSBDH = new PeppolSBDHDocumentReader(IF).extractData(aSBD);
            final ISMPServiceMetadataProvider aSMPClient = new SMPClient(UP, aSBDH.getReceiverAsIdentifier(), ESML.DIGIT_TEST);
            final EndpointType aEndpoint = aSMPClient.getEndpoint(aSBDH.getReceiverAsIdentifier(), aSBDH.getDocumentTypeAsIdentifier(), aSBDH.getProcessAsIdentifier(), ESMPTransportProfile.TRANSPORT_PROFILE_BDXR_AS4);
            if (aEndpoint == null) {
                LOGGER.error("Found no endpoint for:\n  Receiver ID: " + aSBDH.getReceiverAsIdentifier().getURIEncoded() + "\n  Document type ID: " + aSBDH.getDocumentTypeAsIdentifier().getURIEncoded() + "\n  Process ID: " + aSBDH.getProcessAsIdentifier().getURIEncoded());
            } else {
                final KeyStore.PrivateKeyEntry aOurCert = aCF.getPrivateKeyEntry();
                final X509Certificate aTheirCert = CertificateHelper.convertStringToCertficate(aEndpoint.getCertificate());
                final AS4ClientUserMessage aClient = new AS4ClientUserMessage(aResHelper);
                aClient.setSoapVersion(ESoapVersion.SOAP_12);
                // Keystore data
                aClient.setAS4CryptoFactory(aCF);
                aClient.signingParams().setAlgorithmSign(ECryptoAlgorithmSign.RSA_SHA_512);
                aClient.signingParams().setAlgorithmSignDigest(ECryptoAlgorithmSignDigest.DIGEST_SHA_512);
                // FIXME Action, Service etc. are missing
                aClient.setAction("xxx");
                aClient.setServiceType("xxx");
                aClient.setServiceValue("xxx");
                aClient.setConversationID(MessageHelperMethods.createRandomConversationID());
                aClient.setAgreementRefValue("xxx");
                aClient.setFromRole(CAS4.DEFAULT_ROLE);
                aClient.setFromPartyID(PeppolCertificateHelper.getSubjectCN((X509Certificate) aOurCert.getCertificate()));
                aClient.setToRole(CAS4.DEFAULT_ROLE);
                aClient.setToPartyID(PeppolCertificateHelper.getSubjectCN(aTheirCert));
                aClient.ebms3Properties().setAll(MessageHelperMethods.createEbms3Property(CAS4.ORIGINAL_SENDER, aSBDH.getSenderScheme(), aSBDH.getSenderValue()), MessageHelperMethods.createEbms3Property(CAS4.FINAL_RECIPIENT, aSBDH.getReceiverScheme(), aSBDH.getReceiverValue()));
                aClient.setPayload(SBDHWriter.standardBusinessDocument().getAsDocument(aSBD));
                final IAS4ClientBuildMessageCallback aCallback = null;
                final IAS4OutgoingDumper aOutgoingDumper = null;
                final IAS4RetryCallback aRetryCallback = null;
                final AS4ClientSentMessage<byte[]> aResponseEntity = aClient.sendMessageWithRetries(W3CEndpointReferenceHelper.getAddress(aEndpoint.getEndpointReference()), new ResponseHandlerByteArray(), aCallback, aOutgoingDumper, aRetryCallback);
                LOGGER.info("Successfully transmitted document with message ID '" + aResponseEntity.getMessageID() + "' for '" + aSBDH.getReceiverAsIdentifier().getURIEncoded() + "' to '" + W3CEndpointReferenceHelper.getAddress(aEndpoint.getEndpointReference()) + "' in " + aSW.stopAndGetMillis() + " ms");
                if (aResponseEntity.hasResponse()) {
                    final String sMessageID = aResponseEntity.getMessageID();
                    final String sFilename = FilenameHelper.getAsSecureValidASCIIFilename(sMessageID) + "-response.xml";
                    final File aResponseFile = aIncomingDir.resolve(sFilename).toFile();
                    if (SimpleFileIO.writeFile(aResponseFile, aResponseEntity.getResponse()).isSuccess())
                        LOGGER.info("Response file was written to '" + aResponseFile.getAbsolutePath() + "'");
                    else
                        LOGGER.error("Error writing response file to '" + aResponseFile.getAbsolutePath() + "'");
                }
                bSuccess = true;
            }
        }
    } catch (final Exception ex) {
        LOGGER.error("Error sending " + aSendFile.toString(), ex);
    }
    // After the exception handler!
    {
        // Move to done or error directory?
        final Path aDest = aSendFile.resolveSibling(bSuccess ? PATH_DONE : PATH_ERROR).resolve(aSendFile.getFileName());
        try {
            Files.move(aSendFile, aDest);
        } catch (final IOException ex) {
            LOGGER.error("Error moving from '" + aSendFile.toString() + "' to '" + aDest + "'", ex);
        }
    }
}
Also used : Path(java.nio.file.Path) IAS4ClientBuildMessageCallback(com.helger.phase4.client.IAS4ClientBuildMessageCallback) IAS4OutgoingDumper(com.helger.phase4.dump.IAS4OutgoingDumper) PeppolSBDHDocument(com.helger.peppol.sbdh.PeppolSBDHDocument) ISMPServiceMetadataProvider(com.helger.smpclient.peppol.ISMPServiceMetadataProvider) StandardBusinessDocument(org.unece.cefact.namespaces.sbdh.StandardBusinessDocument) ResponseHandlerByteArray(com.helger.httpclient.response.ResponseHandlerByteArray) IAS4RetryCallback(com.helger.phase4.client.IAS4RetryCallback) PeppolSBDHDocumentReader(com.helger.peppol.sbdh.read.PeppolSBDHDocumentReader) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) KeyStore(java.security.KeyStore) X509Certificate(java.security.cert.X509Certificate) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) StopWatch(com.helger.commons.timing.StopWatch) SMPClient(com.helger.smpclient.peppol.SMPClient) EndpointType(com.helger.xsds.peppol.smp1.EndpointType) AS4ClientUserMessage(com.helger.phase4.client.AS4ClientUserMessage) AS4ResourceHelper(com.helger.phase4.util.AS4ResourceHelper) File(java.io.File)

Aggregations

Nonnull (javax.annotation.Nonnull)9 Document (org.w3c.dom.Document)9 AS4ResourceHelper (com.helger.phase4.util.AS4ResourceHelper)7 WSS4JAttachment (com.helger.phase4.attachment.WSS4JAttachment)6 CommonsArrayList (com.helger.commons.collection.impl.CommonsArrayList)5 Phase4Exception (com.helger.phase4.util.Phase4Exception)5 IOException (java.io.IOException)5 Ebms3Error (com.helger.phase4.ebms3header.Ebms3Error)4 File (java.io.File)4 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)4 ErrorList (com.helger.commons.error.list.ErrorList)3 WSS4JAttachmentCallbackHandler (com.helger.phase4.attachment.WSS4JAttachmentCallbackHandler)3 Ebms3UserMessage (com.helger.phase4.ebms3header.Ebms3UserMessage)3 Nullable (javax.annotation.Nullable)3 IHasInputStream (com.helger.commons.io.IHasInputStream)2 HasInputStream (com.helger.commons.io.stream.HasInputStream)2 NonBlockingByteArrayInputStream (com.helger.commons.io.stream.NonBlockingByteArrayInputStream)2 IMimeType (com.helger.commons.mime.IMimeType)2 AS4ClientUserMessage (com.helger.phase4.client.AS4ClientUserMessage)2 Ebms3PullRequest (com.helger.phase4.ebms3header.Ebms3PullRequest)2