com.yubico.u2f.data.messages.ClientData Maven / Gradle / Ivy
package com.yubico.u2f.data.messages;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.yubico.u2f.data.messages.key.util.U2fB64Encoding;
import com.yubico.u2f.exceptions.U2fBadInputException;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Set;
public class ClientData {
private static final String TYPE_PARAM = "typ";
private static final String CHALLENGE_PARAM = "challenge";
private static final String ORIGIN_PARAM = "origin";
private final String type;
private final String challenge;
private final String origin;
private final String rawClientData;
private final JsonNode data;
public String asJson() {
return rawClientData;
}
public ClientData(String clientData) throws U2fBadInputException {
rawClientData = new String(U2fB64Encoding.decode(clientData));
try {
data = new ObjectMapper().readTree(rawClientData);
type = getString(TYPE_PARAM);
challenge = getString(CHALLENGE_PARAM);
origin = getString(ORIGIN_PARAM);
} catch (IOException e) {
throw new U2fBadInputException("Malformed ClientData", e);
}
}
@Override
public String toString() {
return rawClientData;
}
public String getChallenge() {
return challenge;
}
public String getString(String key) {
return data.get(key).asText();
}
public void checkContent(String type, String challenge, Optional> facets) throws U2fBadInputException {
if (!type.equals(this.type)) {
throw new U2fBadInputException("Bad clientData: wrong type " + this.type);
}
if (!challenge.equals(this.challenge)) {
throw new U2fBadInputException("Bad clientData: wrong challenge");
}
if (facets.isPresent()) {
Set allowedFacets = canonicalizeOrigins(facets.get());
String canonicalOrigin;
try {
canonicalOrigin = canonicalizeOrigin(origin);
} catch (RuntimeException e) {
throw new U2fBadInputException("Bad clientData: Malformed origin", e);
}
verifyOrigin(canonicalOrigin, allowedFacets);
}
}
private static void verifyOrigin(String origin, Set allowedOrigins) throws U2fBadInputException {
if (!allowedOrigins.contains(origin)) {
throw new U2fBadInputException(origin +
" is not a recognized facet for this application");
}
}
public static Set canonicalizeOrigins(Set origins) {
ImmutableSet.Builder result = ImmutableSet.builder();
for (String origin : origins) {
result.add(canonicalizeOrigin(origin));
}
return result.build();
}
public static String canonicalizeOrigin(String url) {
try {
URI uri = new URI(url);
if (uri.getAuthority() == null) {
return url;
}
return uri.getScheme() + "://" + uri.getAuthority();
} catch (URISyntaxException e) {
throw new IllegalArgumentException("specified bad origin", e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy