Skip to content

Commit 141fcd0

Browse files
committed
Added IAS4IncomingMessageState.get(Signing|Decrypting)Certificate
1 parent be5f4c8 commit 141fcd0

File tree

9 files changed

+118
-51
lines changed

9 files changed

+118
-51
lines changed

phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingHandler.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ public static void parseAS4Message (@Nonnull final IAS4IncomingAttachmentFactory
179179
final IMimeType aPlainContentType = aContentType.getCopyWithoutParameters ();
180180

181181
// Fallback to global dumper if none is provided
182-
final IAS4IncomingDumper aRealIncomingDumper = aIncomingDumper != null ? aIncomingDumper
183-
: AS4DumpManager.getIncomingDumper ();
182+
final IAS4IncomingDumper aRealIncomingDumper = aIncomingDumper != null ? aIncomingDumper : AS4DumpManager
183+
.getIncomingDumper ();
184184

185185
Document aSoapDocument = null;
186186
ESoapVersion eSoapVersion = null;
@@ -477,8 +477,7 @@ private static void _processSoapHeaderElements (@Nonnull final SoapHeaderElement
477477
aHeader.getNode (),
478478
aIncomingAttachments,
479479
aIncomingState,
480-
aProcessingErrorMessagesTarget)
481-
.isSuccess ())
480+
aProcessingErrorMessagesTarget).isSuccess ())
482481
{
483482
// Mark header as processed (for mustUnderstand check)
484483
aHeader.setProcessed (true);
@@ -740,7 +739,7 @@ public static IAS4IncomingMessageState processEbmsMessage (@Nonnull @WillNotClos
740739
aValidator.validatePMode (aPMode, aErrorList, EAS4ProfileValidationMode.USER_MESSAGE);
741740
aValidator.validateUserMessage (aEbmsUserMessage, aErrorList);
742741
aValidator.validateInitiatorIdentity (aEbmsUserMessage,
743-
aIncomingState.getUsedCertificate (),
742+
aIncomingState.getSigningCertificate (),
744743
aMessageMetadata,
745744
aErrorList);
746745
if (aErrorList.isNotEmpty ())

phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingMessageState.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ public final class AS4IncomingMessageState extends AttributeContainerAny <String
7575
private static final String KEY_SOAP_BODY_PAYLOAD_PRESENT = "phase4.soap.body.payload.present";
7676
private static final String KEY_INITIATOR_ID = "phase4.initiator.id";
7777
private static final String KEY_RESPONDER_ID = "phase4.responder.id";
78+
@Deprecated (forRemoval = true, since = "3.0.5")
7879
private static final String KEY_USED_CERTIFICATE = "phase4.used.certificate";
80+
private static final String KEY_SIGNING_CERTIFICATE = "phase4.signing.certificate";
81+
private static final String KEY_DECRYPTING_CERTIFICATE = "phase4.decryting.certificate";
7982
private static final String KEY_EFFECTIVE_PMODE_LEG = "phase4.pmode.effective.leg";
8083
private static final String KEY_EFFECTIVE_PMODE_LEG_NUMBER = "phase4.pmode.effective.leg.number";
8184
private static final String KEY_WSS4J_SECURITY_ACTIONS = "phase4.soap.wss4j-security-actions";
@@ -256,16 +259,40 @@ public void setResponderID (@Nullable final String sResponderID)
256259
}
257260

258261
@Nullable
262+
@Deprecated (forRemoval = true, since = "3.0.5")
259263
public X509Certificate getUsedCertificate ()
260264
{
261265
return getCastedValue (KEY_USED_CERTIFICATE);
262266
}
263267

268+
@Deprecated (forRemoval = true, since = "3.0.5")
264269
public void setUsedCertificate (@Nullable final X509Certificate aCert)
265270
{
266271
putIn (KEY_USED_CERTIFICATE, aCert);
267272
}
268273

274+
@Nullable
275+
public X509Certificate getSigningCertificate ()
276+
{
277+
return getCastedValue (KEY_SIGNING_CERTIFICATE);
278+
}
279+
280+
public void setSigningCertificate (@Nullable final X509Certificate aCert)
281+
{
282+
putIn (KEY_SIGNING_CERTIFICATE, aCert);
283+
}
284+
285+
@Nullable
286+
public X509Certificate getDecryptingCertificate ()
287+
{
288+
return getCastedValue (KEY_DECRYPTING_CERTIFICATE);
289+
}
290+
291+
public void setDecryptingCertificate (@Nullable final X509Certificate aCert)
292+
{
293+
putIn (KEY_DECRYPTING_CERTIFICATE, aCert);
294+
}
295+
269296
@Nullable
270297
public PModeLeg getEffectivePModeLeg ()
271298
{

phase4-lib/src/main/java/com/helger/phase4/incoming/IAS4IncomingMessageState.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,18 +351,60 @@ default boolean hasResponderID ()
351351
* @see #hasUsedCertificate()
352352
*/
353353
@Nullable
354+
@Deprecated (forRemoval = true, since = "3.0.5")
354355
X509Certificate getUsedCertificate ();
355356

356357
/**
357358
* @return <code>true</code> if a certificate is provided, <code>false</code>
358359
* if not.
359360
* @see #getUsedCertificate()
360361
*/
362+
@Deprecated (forRemoval = true, since = "3.0.5")
361363
default boolean hasUsedCertificate ()
362364
{
363365
return getUsedCertificate () != null;
364366
}
365367

368+
/**
369+
* @return The signing certificate in the incoming message. May be
370+
* <code>null</code>.
371+
* @see #hasSigningCertificate()
372+
* @since 3.0.5
373+
*/
374+
@Nullable
375+
X509Certificate getSigningCertificate ();
376+
377+
/**
378+
* @return <code>true</code> if a signing certificate is provided,
379+
* <code>false</code> if not.
380+
* @see #getSigningCertificate()
381+
* @since 3.0.5
382+
*/
383+
default boolean hasSigningCertificate ()
384+
{
385+
return getSigningCertificate () != null;
386+
}
387+
388+
/**
389+
* @return The decrypting certificate in the incoming message. May be
390+
* <code>null</code>.
391+
* @see #hasDecryptingCertificate()
392+
* @since 3.0.5
393+
*/
394+
@Nullable
395+
X509Certificate getDecryptingCertificate ();
396+
397+
/**
398+
* @return <code>true</code> if a decrypting certificate is provided,
399+
* <code>false</code> if not.
400+
* @see #getDecryptingCertificate()
401+
* @since 3.0.5
402+
*/
403+
default boolean hasDecryptingCertificate ()
404+
{
405+
return getDecryptingCertificate () != null;
406+
}
407+
366408
/**
367409
* @return The effective leg to use. May be leg 1 or leg 2 of the PMode. If no
368410
* PMode was found, no PModeLeg is present.

phase4-lib/src/main/java/com/helger/phase4/incoming/soap/SoapHeaderElementProcessorWSS4J.java

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ public SoapHeaderElementProcessorWSS4J (@Nonnull final IAS4CryptoFactory aCrypto
108108
m_aDecryptParameterModifier = aDecryptParameterModifier;
109109
}
110110

111+
@SuppressWarnings ("removal")
111112
@Nonnull
112113
private ESuccess _verifyAndDecrypt (@Nonnull final Document aSOAPDoc,
113114
@Nonnull final ICommonsList <WSS4JAttachment> aAttachments,
@@ -225,8 +226,10 @@ private ESuccess _verifyAndDecrypt (@Nonnull final Document aSOAPDoc,
225226

226227
// Collect all unique used certificates
227228
final ICommonsSet <X509Certificate> aCertSet = new CommonsHashSet <> ();
228-
// Preferred certificate from BinarySecurityToken
229-
X509Certificate aPreferredCert = null;
229+
// The certificate used for signing
230+
X509Certificate aSigningCert = null;
231+
// The certificate used for decrypting
232+
X509Certificate aDecryptingCert = null;
230233
int nWSS4JSecurityActions = 0;
231234
for (final WSSecurityEngineResult aResult : aResults)
232235
{
@@ -241,36 +244,31 @@ private ESuccess _verifyAndDecrypt (@Nonnull final Document aSOAPDoc,
241244
if (aCert != null)
242245
{
243246
aCertSet.add (aCert);
244-
if (nAction == WSConstants.BST && aPreferredCert == null)
245-
aPreferredCert = aCert;
247+
if (nAction == WSConstants.SIGN)
248+
{
249+
if (aSigningCert == null)
250+
aSigningCert = aCert;
251+
else
252+
if (aSigningCert != aCert)
253+
LOGGER.warn ("Found a second signing certificate");
254+
}
255+
if (nAction == WSConstants.ENCR)
256+
{
257+
if (aDecryptingCert == null)
258+
aDecryptingCert = aCert;
259+
else
260+
if (aDecryptingCert != aCert)
261+
LOGGER.warn ("Found a second decryption certificate");
262+
}
246263
}
247264
}
248265
// this determines if a signature check or a decryption happened
249266
aIncomingState.setSoapWSS4JSecurityActions (nWSS4JSecurityActions);
250267

251-
final X509Certificate aUsedCert;
252-
if (aCertSet.size () > 1)
253-
{
254-
if (aPreferredCert == null)
255-
{
256-
LOGGER.warn ("Found " + aCertSet.size () + " different certificates in message. Using the first one.");
257-
if (LOGGER.isDebugEnabled ())
258-
LOGGER.debug ("All gathered certificates: " + aCertSet);
259-
aUsedCert = aCertSet.getAtIndex (0);
260-
}
261-
else
262-
aUsedCert = aPreferredCert;
263-
}
264-
else
265-
{
266-
if (aCertSet.size () == 1)
267-
aUsedCert = aCertSet.getAtIndex (0);
268-
else
269-
aUsedCert = null;
270-
}
271-
272268
// Remember in State
273-
aIncomingState.setUsedCertificate (aUsedCert);
269+
aIncomingState.setUsedCertificate (aSigningCert);
270+
aIncomingState.setSigningCertificate (aSigningCert);
271+
aIncomingState.setDecryptingCertificate (aDecryptingCert);
274272
aIncomingState.setDecryptedSoapDocument (aSOAPDoc);
275273

276274
LOGGER.info ("phase4 --- attachment.storetemp:start");
@@ -305,7 +303,7 @@ private ESuccess _verifyAndDecrypt (@Nonnull final Document aSOAPDoc,
305303
catch (final IndexOutOfBoundsException | IllegalStateException | WSSecurityException ex)
306304
{
307305
/**
308-
* Error processing the WSSSecurity Header
306+
* Error processing the WSSecurity Header
309307
*
310308
* <pre>
311309
* java.lang.IndexOutOfBoundsException: null
@@ -331,7 +329,7 @@ private ESuccess _verifyAndDecrypt (@Nonnull final Document aSOAPDoc,
331329
at com.helger.phase4.servlet.soap.SOAPHeaderElementProcessorWSS4J._verifyAndDecrypt(SOAPHeaderElementProcessorWSS4J.java:187) ~[classes/:?]
332330
* </pre>
333331
*
334-
* Error processing the WSSSecurity Header
332+
* Error processing the WSSecurity Header
335333
*
336334
* <pre>
337335
org.apache.wss4j.common.ext.WSSecurityException: Error during certificate path validation: No trusted certs found
@@ -359,7 +357,7 @@ private ESuccess _verifyAndDecrypt (@Nonnull final Document aSOAPDoc,
359357
*/
360358

361359
// Decryption or Signature check failed
362-
String sDetails = "Error processing the WSSSecurity Header";
360+
String sDetails = "Error processing the WSSecurity Header";
363361
if (ex instanceof WSSecurityException)
364362
{
365363
sDetails += " (WS Security error: " + ((WSSecurityException) ex).getErrorCode () + ")";

phase4-lib/src/main/java/com/helger/phase4/model/error/Ebms3ErrorBuilder.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,14 @@ public Ebms3ErrorBuilder description (@Nullable final Ebms3Description a)
9595
public Ebms3ErrorBuilder errorDetail (@Nullable final String s, @Nullable final Throwable t)
9696
{
9797
// Be able to allow disabling sending stack traces (see #225)
98+
String sErrorDetail = s;
9899
final Throwable aLogT = AS4Configuration.isIncludeStackTraceInErrorMessages () ? t : null;
99-
return errorDetail (StringHelper.getConcatenatedOnDemand (s,
100-
": ",
101-
aLogT == null ? "" : "Technical details: " +
102-
StringHelper.getConcatenatedOnDemand (aLogT.getClass ()
103-
.getName (),
104-
" - ",
105-
aLogT.getMessage ())));
100+
if (aLogT != null)
101+
{
102+
sErrorDetail += ": Technical details: " +
103+
StringHelper.getConcatenatedOnDemand (aLogT.getClass ().getName (), " - ", aLogT.getMessage ());
104+
}
105+
return errorDetail (sErrorDetail);
106106
}
107107

108108
@Nonnull

phase4-peppol-server-webapp/src/main/java/com/helger/phase4/peppol/server/spi/StoringPeppolIncomingSBDHandlerSPI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public void handleIncomingSBD (@Nonnull final IAS4IncomingMessageMetadata aMessa
7171
// Example code snippets how to get data
7272
LOGGER.info ("Received a new Peppol Message");
7373
LOGGER.info (" C1 = " + aPeppolSBD.getSenderAsIdentifier ().getURIEncoded ());
74-
LOGGER.info (" C2 = " + PeppolCertificateHelper.getSubjectCN (aIncomingState.getUsedCertificate ()));
74+
LOGGER.info (" C2 = " + PeppolCertificateHelper.getSubjectCN (aIncomingState.getSigningCertificate ()));
7575
LOGGER.info (" C3 = " + sMyPeppolSeatID);
7676
LOGGER.info (" C4 = " + aPeppolSBD.getReceiverAsIdentifier ().getURIEncoded ());
7777
LOGGER.info (" DocType = " + aPeppolSBD.getDocumentTypeAsIdentifier ().getURIEncoded ());

phase4-peppol-server-webapp/src/main/java/com/helger/phase4/peppol/server/spi/StoringServletMessageProcessorSPI.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,13 @@ private static void _dumpSoap (@Nonnull final IAS4IncomingMessageMetadata aMessa
8989
}
9090
}
9191

92-
if (aIncomingState.hasUsedCertificate ())
92+
if (aIncomingState.hasSigningCertificate ())
9393
{
9494
// Dump the senders certificate as PEM file
9595
// That can usually extracted from the Binary Security Token of the SOAP
9696
final File aFile = StorageHelper.getStorageFile (aMessageMetadata, ".pem");
97-
final X509Certificate aUsedCert = aIncomingState.getUsedCertificate ();
98-
final String sPEM = CertificateHelper.getPEMEncodedCertificate (aUsedCert);
97+
final X509Certificate aSigningCert = aIncomingState.getSigningCertificate ();
98+
final String sPEM = CertificateHelper.getPEMEncodedCertificate (aSigningCert);
9999
final byte [] aBytes = sPEM.getBytes (StandardCharsets.US_ASCII);
100100
if (SimpleFileIO.writeFile (aFile, aBytes).isFailure ())
101101
{

phase4-peppol-servlet/src/main/java/com/helger/phase4/peppol/servlet/Phase4PeppolServletMessageProcessorSPI.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ public static PeppolReportingItem createPeppolReportingItemForReceivedMessage (@
476476
}
477477

478478
// Incoming message signed by C2
479-
final String sC2ID = PeppolCertificateHelper.getSubjectCN (aState.getUsedCertificate ());
479+
final String sC2ID = PeppolCertificateHelper.getSubjectCN (aState.getSigningCertificate ());
480480

481481
try
482482
{
@@ -608,12 +608,13 @@ public AS4MessageProcessorResult processAS4UserMessage (@Nonnull final IAS4Incom
608608
if (aReceiverCheckData.isCheckSigningCertificateRevocation ())
609609
{
610610
final OffsetDateTime aNow = MetaAS4Manager.getTimestampMgr ().getCurrentDateTime ();
611-
final X509Certificate aSenderCert = aState.getUsedCertificate ();
611+
final X509Certificate aSenderSigningCert = aState.getSigningCertificate ();
612612
// Check if signing AP certificate is revoked
613613
// * Use global caching setting
614614
// * Use global certificate check mode
615615
final EPeppolCertificateCheckResult eCertCheckResult = aReceiverCheckData.getAPCAChecker ()
616-
.checkCertificate (aSenderCert, aNow);
616+
.checkCertificate (aSenderSigningCert,
617+
aNow);
617618
if (eCertCheckResult.isInvalid ())
618619
{
619620
final String sDetails = "The received Peppol message is signed with a Peppol AP certificate invalid at " +

phase4-server-webapp/src/main/java/com/helger/phase4/server/spi/ExampleReceiveMessageProcessorSPI.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ private static void _dumpSoap (@Nonnull final IAS4IncomingMessageMetadata aMessa
7777
LOGGER.info ("Wrote SOAP to '" + aFile.getAbsolutePath () + "'");
7878
}
7979

80-
if (aState.hasUsedCertificate ())
80+
if (aState.hasSigningCertificate ())
8181
{
8282
// Dump the senders certificate as PEM file
8383
// That can usually extracted from the Binary Security Token of the SOAP
8484
final File aFile = StorageHelper.getStorageFile (aMessageMetadata, ".pem");
85-
final X509Certificate aUsedCert = aState.getUsedCertificate ();
86-
final String sPEM = CertificateHelper.getPEMEncodedCertificate (aUsedCert);
85+
final X509Certificate aSigningCert = aState.getSigningCertificate ();
86+
final String sPEM = CertificateHelper.getPEMEncodedCertificate (aSigningCert);
8787
final byte [] aBytes = sPEM.getBytes (StandardCharsets.US_ASCII);
8888
if (SimpleFileIO.writeFile (aFile, aBytes).isFailure ())
8989
LOGGER.error ("Failed to write certificate to '" + aFile.getAbsolutePath () + "'");

0 commit comments

Comments
 (0)