/** * Checks to see whether the schema type of the subject confirmation data, if present, is the * required {@link KeyInfoConfirmationDataType#TYPE_NAME}. * * @param confirmation subject confirmation bearing the confirmation data to be checked * @return true if the confirmation data's schema type is correct, false otherwise * @throws AssertionValidationException thrown if there is a problem validating the confirmation * data type */ protected boolean isValidConfirmationDataType(@Nonnull final SubjectConfirmation confirmation) throws AssertionValidationException { QName confirmationDataSchemaType = confirmation.getSubjectConfirmationData().getSchemaType(); if (confirmationDataSchemaType != null && !confirmationDataSchemaType.equals(KeyInfoConfirmationDataType.TYPE_NAME)) { log.debug( "SubjectConfirmationData xsi:type was non-null and did not match {}", KeyInfoConfirmationDataType.TYPE_NAME); return false; } log.debug( "SubjectConfirmationData xsi:type was either null or matched {}", KeyInfoConfirmationDataType.TYPE_NAME); return true; }
/** * Extracts the {@link KeyInfo}s from the given subject confirmation data. * * @param confirmation subject confirmation data * @param assertion assertion bearing the subject to be confirmed * @param context current message processing context * @return list of key informations available in the subject confirmation data, never null * @throws AssertionValidationException if there is a problem processing the SubjectConfirmation */ @Nonnull protected List<KeyInfo> getSubjectConfirmationKeyInformation( @Nonnull final SubjectConfirmation confirmation, @Nonnull final Assertion assertion, @Nonnull final ValidationContext context) throws AssertionValidationException { SubjectConfirmationData confirmationData = confirmation.getSubjectConfirmationData(); List<KeyInfo> keyInfos = new LazyList<>(); for (XMLObject object : confirmationData.getUnknownXMLObjects(KeyInfo.DEFAULT_ELEMENT_NAME)) { if (object != null) { keyInfos.add((KeyInfo) object); } } log.debug("Found '{}' KeyInfo children of SubjectConfirmationData", keyInfos.size()); return keyInfos; }
/** {@inheritDoc} */ @Nonnull protected ValidationResult doValidate( @Nonnull final SubjectConfirmation confirmation, @Nonnull final Assertion assertion, @Nonnull final ValidationContext context) throws AssertionValidationException { if (!Objects.equals(confirmation.getMethod(), SubjectConfirmation.METHOD_HOLDER_OF_KEY)) { return ValidationResult.INDETERMINATE; } log.debug("Attempting holder-of-key subject confirmation"); if (!isValidConfirmationDataType(confirmation)) { String msg = String.format( "Subject confirmation data is not of type '%s'", KeyInfoConfirmationDataType.TYPE_NAME); log.debug(msg); context.setValidationFailureMessage(msg); return ValidationResult.INVALID; } List<KeyInfo> possibleKeys = getSubjectConfirmationKeyInformation(confirmation, assertion, context); if (possibleKeys.isEmpty()) { String msg = String.format( "No key information for holder of key subject confirmation in assertion '%s'", assertion.getID()); log.debug(msg); context.setValidationFailureMessage(msg); return ValidationResult.INVALID; } Pair<PublicKey, X509Certificate> keyCertPair = null; try { keyCertPair = getKeyAndCertificate(context); } catch (IllegalArgumentException e) { log.warn("Problem with the validation context presenter key/cert params: {}", e.getMessage()); context.setValidationFailureMessage( "Unable to obtain presenter key/cert params from validation context"); return ValidationResult.INDETERMINATE; } if (keyCertPair.getFirst() == null && keyCertPair.getSecond() == null) { log.debug("Neither the presenter's certificate nor its public key were provided"); context.setValidationFailureMessage( "Neither the presenter's certificate nor its public key were provided"); return ValidationResult.INDETERMINATE; } for (KeyInfo keyInfo : possibleKeys) { if (matchesKeyValue(keyCertPair.getFirst(), keyInfo)) { log.debug( "Successfully matched public key in subject confirmation data to supplied key param"); context .getDynamicParameters() .put(SAML2AssertionValidationParameters.SC_HOK_CONFIRMED_KEYINFO, keyInfo); return ValidationResult.VALID; } else if (matchesX509Certificate(keyCertPair.getSecond(), keyInfo)) { log.debug( "Successfully matched certificate in subject confirmation data to supplied cert param"); context .getDynamicParameters() .put(SAML2AssertionValidationParameters.SC_HOK_CONFIRMED_KEYINFO, keyInfo); return ValidationResult.VALID; } } return ValidationResult.INVALID; }