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;
}
}
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();
}
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);
}
}
}
Aggregations