diff --git a/docs/getting-started/event-log/set-validation.mdx b/docs/getting-started/event-log/set-validation.mdx index 59c13296247ded0eff304ca0a93062bbec3ff60d..5deaa0a7b17f677bd04eeac9f68d778ab377d04e 100644 --- a/docs/getting-started/event-log/set-validation.mdx +++ b/docs/getting-started/event-log/set-validation.mdx @@ -90,30 +90,71 @@ values={[ <TabItem value="java"> -Im folgenden Beispiel kann die allgemeine Struktur eines SET über folgenden Code validiert werden. -Die Prüfungen bauen auf der Methode `assertTrue` auf. +Im folgenden Beispiel kann die allgemeine Struktur eines SET über folgenden Code validiert werden. +Außerdem wird der Schlüssel verifiziert. +Die Prüfungen bauen auf der Methode `validateTrueOrElseThrow` auf. Die Methode prüft, ob ein Ausdruck der Wahrheit entspricht. Diese kann im Fehlerfall die Fehler sammeln oder direkt eine Exception werfen. ```java public void validate(SignedJWT signedJWT, UUID caseId, FitConnectKeyLookup keyLookup) { try { - final JWSHeader header = signedJWT.getHeader(); - validateHeader(header); - // - final JWTClaimsSet payload = signedJWT.getJWTClaimsSet(); - validatePayload(payload); - validateSubject(payload); - // - validateTxnClaim(signedJWT.getJWTClaimsSet(), caseId); - // - validateSignature(signedJWT, keyLookup); - } catch (Exception e) { - fail(e.getMessage()); - } + validateHeader(signedJWT.getHeader()); + validatePayload(signedJWT.getJWTClaimsSet()); + + String subject = payload.getStringClaim("sub"); + String tokenSubmissionId = subject.substring(subject.indexOf(':') + 1); + validateTrueOrElseThrow(tokenSubmissionId.equalsIgnoreCase(submissionId), "The provided subject does not match with the submission."); + + String txn = payload.getStringClaim("txn"); + String transactionId = txn.substring(txn.indexOf(':') + 1); + validateTrueOrElseThrow(transactionId.equalsIgnoreCase(caseId), "The provided txn does not match with the case."); + + UUID jti = UUID.fromString(payload.getStringClaim("jti")); + + + try { + // Validate public Key + RSAKey parsedPublicKey = RSAKey.parse(publicKey); + validateRSAKey(parsedPublicKey, false); + JWSVerifier jwsVerifier = new RSASSAVerifier(parsedPublicKey); + + validateTrueOrElseThrow(signedJWT.verify(jwsVerifier), "The signature of the token could not be verified with the specified key."); + } catch (ParseException | JOSEException e) { + throw new RuntimeException("The SET could not get parsed properly."); + } + } catch (AssertionError e) { + throw new RuntimeException(e.getMessage()); + } } + + public static void validateRSAKey(RSAKey RSAKey, boolean isPrivate){ + validateTrueOrElseThrow(RSAKey.getModulus().decodeToBigInteger().bitLength() >= 4096, "JWK has wrong key length."); + validateTrueOrElseThrow(RSAKey.getAlgorithm().equals(JWSAlgorithm.PS512), "The specified public key does not use PS512 as algorithm."); + + if(isPrivate){ + validateTrueOrElseThrow(RSAKey.getKeyOperations().size() == 1 && + RSAKey.getKeyOperations().contains(KeyOperation.SIGN), + "The specified private key is not intended for 'sign' as specified through key operation.") + } + else{ + validateTrueOrElseThrow(RSAKey.getKeyOperations().size() == 1 && + RSAKey.getKeyOperations().contains(KeyOperation.VERIFY), + "The specified public key is not intended for 'verify' as specified through key operation.") + }; + validateTrueOrElseThrow(RSAKey.getPublicExponent().toString().equals("AQAB"), "The specified key does not match the public exponent 'AQAB'."); + + } + + private static void validateTrueOrElseThrow(boolean expression, String msg) { + if (!expression) { + throw new RuntimeException(msg); + } + } + + ``` -Der Header wird auf die drei verpflichtenden Angaben geprüft. +Der folgende Quellcode prüft, ob der Header Pflichtangaben enthält: ```java private void validateHeader(JWSHeader header) {