// Copyright 2017 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.webauthn.gaedemo.objects; import java.nio.charset.StandardCharsets; import com.google.common.io.BaseEncoding; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.webauthn.gaedemo.exceptions.ResponseException; import com.googlecode.objectify.annotation.Subclass; import co.nstant.in.cbor.CborException; @Subclass public class AuthenticatorAttestationResponse extends AuthenticatorResponse { private static class AttestationResponseJson { String clientDataJSON; String attestationObject; String[] transports; } public AttestationObject decodedObject; public String[] transports; /** * */ public AuthenticatorAttestationResponse() {} /** * Create AuthenticatorAttestationResponse from member objects. * @param clientDataJSON * @param attestationObject * @throws ResponseException */ public AuthenticatorAttestationResponse(String clientDataJSON, String attestationObject) throws ResponseException { clientData = CollectedClientData.decode(clientDataJSON); clientDataBytes = clientDataJSON.getBytes(StandardCharsets.UTF_8); try { decodedObject = AttestationObject.decode(BaseEncoding.base64().decode(attestationObject)); } catch (CborException e) { throw new ResponseException("Cannot decode attestation object"); } } /** * @param data * @throws ResponseException */ public AuthenticatorAttestationResponse(JsonElement data) throws ResponseException { Gson gson = new Gson(); AttestationResponseJson parsedObject = gson.fromJson(data, AttestationResponseJson.class); clientDataBytes = BaseEncoding.base64().decode(parsedObject.clientDataJSON); byte[] attestationObject = BaseEncoding.base64().decode(parsedObject.attestationObject); try { decodedObject = AttestationObject.decode(attestationObject); } catch (CborException e) { throw new ResponseException("Cannot decode attestation object"); } clientData = gson.fromJson(new String(clientDataBytes, StandardCharsets.UTF_8), CollectedClientData.class); transports = parsedObject.transports; } /** * @return json encoded representation of the AuthenticatorAttestationResponse */ public String encode() { JsonObject json = new JsonObject(); json.addProperty("clientDataJSON", BaseEncoding.base64().encode(clientDataBytes)); try { json.addProperty("attestationObject", BaseEncoding.base64().encode(decodedObject.encode())); } catch (CborException e) { return null; } return json.getAsString(); } /** * @return the decodedObject */ public AttestationObject getAttestationObject() { return decodedObject; } /** * @return the list of transports supported by the credential */ public String[] getTransports() { return transports; } }