use of com.yubico.webauthn.data.ByteArray in project cas by apereo.
the class WebAuthnServer method startRegistration.
public Either<String, RegistrationRequest> startRegistration(@NonNull final String username, final Optional<String> displayName, final Optional<String> credentialNickname, final ResidentKeyRequirement residentKeyRequirement, final Optional<ByteArray> sessionToken) throws ExecutionException {
LOGGER.trace("startRegistration username: {}, credentialNickname: {}", username, credentialNickname);
var registrations = userStorage.getRegistrationsByUsername(username);
var existingUser = registrations.stream().findAny().map(CredentialRegistration::getUserIdentity);
val permissionGranted = existingUser.map(userIdentity -> sessions.isSessionForUser(userIdentity.getId(), sessionToken)).orElse(true);
if (permissionGranted) {
var registrationUserId = existingUser.orElseGet(() -> UserIdentity.builder().name(username).displayName(displayName.get()).id(generateRandom(32)).build());
val request = new RegistrationRequest(username, credentialNickname, generateRandom(32), rp.startRegistration(StartRegistrationOptions.builder().user(registrationUserId).authenticatorSelection(AuthenticatorSelectionCriteria.builder().residentKey(residentKeyRequirement).build()).build()), Optional.of(sessions.createSession(registrationUserId.getId())));
registerRequestStorage.put(request.getRequestId(), request);
return Either.right(request);
} else {
return Either.left("The username \"" + username + "\" is already registered.");
}
}
use of com.yubico.webauthn.data.ByteArray in project cas by apereo.
the class ExtensionMatcher method matches.
@Override
public boolean matches(X509Certificate attestationCertificate, JsonNode parameters) {
String matchKey = parameters.get(EXTENSION_KEY).asText();
JsonNode matchValue = parameters.get(EXTENSION_VALUE);
byte[] extensionValue = attestationCertificate.getExtensionValue(matchKey);
if (extensionValue != null) {
if (matchValue == null) {
return true;
} else {
try {
final ASN1Primitive value = ASN1Primitive.fromByteArray(extensionValue);
if (matchValue.isObject()) {
if (matchTypedValue(matchKey, matchValue, value)) {
return true;
}
} else if (matchValue.isTextual()) {
if (matchStringValue(matchKey, matchValue, value))
return true;
}
} catch (IOException e) {
LOGGER.error("Failed to parse extension value as ASN1: {}", new ByteArray(extensionValue).getHex(), e);
}
}
}
return false;
}
use of com.yubico.webauthn.data.ByteArray in project java-webauthn-server by Yubico.
the class FidoMetadataDownloader method verifyHash.
/**
* @return <code>contents</code> if its SHA-256 hash matches any element of <code>
* acceptedCertSha256</code>, otherwise <code>null</code>.
*/
private static ByteArray verifyHash(ByteArray contents, Set<ByteArray> acceptedCertSha256) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
final ByteArray hash = new ByteArray(digest.digest(contents.getBytes()));
if (acceptedCertSha256.stream().anyMatch(acceptableHash -> acceptableHash.equals(hash))) {
return contents;
} else {
return null;
}
}
use of com.yubico.webauthn.data.ByteArray in project java-webauthn-server by Yubico.
the class FidoMetadataDownloader method parseAndVerifyBlob.
private MetadataBLOB parseAndVerifyBlob(ByteArray jwt, X509Certificate trustRootCertificate) throws CertPathValidatorException, InvalidAlgorithmParameterException, CertificateException, IOException, NoSuchAlgorithmException, SignatureException, InvalidKeyException, Base64UrlException, FidoMetadataDownloaderException {
Scanner s = new Scanner(new ByteArrayInputStream(jwt.getBytes())).useDelimiter("\\.");
final ByteArray header = ByteArray.fromBase64Url(s.next());
final ByteArray payload = ByteArray.fromBase64Url(s.next());
final ByteArray signature = ByteArray.fromBase64Url(s.next());
return verifyBlob(header, payload, signature, trustRootCertificate);
}
use of com.yubico.webauthn.data.ByteArray in project java-webauthn-server by Yubico.
the class FidoMetadataService method findEntries.
/**
* Look up metadata entries matching a given attestation certificate chain or AAGUID.
*
* @param attestationCertificateChain an attestation certificate chain, presumably from a WebAuthn
* attestation statement.
* @param aaguid the AAGUID of the authenticator to look up, if available.
* @return All metadata entries which satisfy ALL of the following:
* <ul>
* <li>It satisfies the {@link FidoMetadataServiceBuilder#prefilter(Predicate) prefilter}.
* <li>It satisfies AT LEAST ONE of the following:
* <ul>
* <li><code>aaguid</code> is present and equals the {@link
* MetadataBLOBPayloadEntry#getAaguid() AAGUID} of the metadata entry.
* <li><code>aaguid</code> is present and equals the {@link
* MetadataBLOBPayloadEntry#getAaguid() AAGUID} of the {@link
* MetadataBLOBPayloadEntry#getMetadataStatement() metadata statement}, if any, in
* the metadata entry.
* <li>The certificate subject key identifier of any certificate in <code>
* attestationCertificateChain</code> matches any element of {@link
* MetadataBLOBPayloadEntry#getAttestationCertificateKeyIdentifiers()
* attestationCertificateKeyIdentifiers} in the metadata entry.
* <li>The certificate subject key identifier of any certificate in <code>
* attestationCertificateChain</code> matches any element of {@link
* MetadataStatement#getAttestationCertificateKeyIdentifiers()
* attestationCertificateKeyIdentifiers} in the {@link
* MetadataBLOBPayloadEntry#getMetadataStatement() metadata statement}, if any, in
* the metadata entry.
* </ul>
* <li>It satisfies the {@link FidoMetadataServiceBuilder#filter(Predicate) filter} together
* with <code>attestationCertificateChain</code> and <code>aaguid</code>.
* </ul>
*
* @see #findEntries(List)
* @see #findEntries(List, AAGUID)
*/
public Set<MetadataBLOBPayloadEntry> findEntries(@NonNull List<X509Certificate> attestationCertificateChain, @NonNull Optional<AAGUID> aaguid) {
final Set<String> certSubjectKeyIdentifiers = attestationCertificateChain.stream().map(cert -> {
try {
return new ByteArray(CertificateParser.computeSubjectKeyIdentifier(cert)).getHex();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA-1 hash algorithm is not available in JCA context.", e);
}
}).collect(Collectors.toSet());
final Optional<AAGUID> nonzeroAaguid = aaguid.filter(a -> !a.isZero());
log.debug("findEntries(certSubjectKeyIdentifiers = {}, aaguid = {})", certSubjectKeyIdentifiers, aaguid);
if (!nonzeroAaguid.isPresent()) {
log.debug("findEntries: ignoring zero AAGUID");
}
final Set<MetadataBLOBPayloadEntry> result = Stream.concat(nonzeroAaguid.map(prefilteredEntriesByAaguid::get).map(Collection::stream).orElseGet(Stream::empty), certSubjectKeyIdentifiers.stream().flatMap(cski -> Optional.ofNullable(prefilteredEntriesByCertificateKeyIdentifier.get(cski)).map(Collection::stream).orElseGet(Stream::empty))).filter(metadataBLOBPayloadEntry -> this.filter.test(new AuthenticatorToBeFiltered(attestationCertificateChain, metadataBLOBPayloadEntry, aaguid.orElse(null)))).collect(Collectors.toSet());
log.debug("findEntries(certSubjectKeyIdentifiers = {}, aaguid = {}) => {} matches", certSubjectKeyIdentifiers, aaguid, result.size());
return result;
}
Aggregations