All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yubico.webauthn.data.PublicKeyCredential Maven / Gradle / Ivy

There is a newer version: 2.6.0-alpha7
Show newest version
// Copyright (c) 2018, Yubico AB
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package com.yubico.webauthn.data;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.yubico.internal.util.JacksonCodecs;
import com.yubico.webauthn.AssertionResult;
import com.yubico.webauthn.FinishAssertionOptions;
import com.yubico.webauthn.FinishRegistrationOptions;
import com.yubico.webauthn.RegistrationResult;
import com.yubico.webauthn.RelyingParty;
import java.io.IOException;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;

/**
 * The PublicKeyCredential interface inherits from Credential [CREDENTIAL-MANAGEMENT-1], and contains
 * the attributes that are returned to the caller when a new credential is created, or a new
 * assertion is requested.
 *
 * @see §5.1.
 *     PublicKeyCredential Interface
 */
@Value
@Builder(toBuilder = true)
public class PublicKeyCredential<
    A extends AuthenticatorResponse, B extends ClientExtensionOutputs> {

  /**
   * The raw Credential ID of this credential, corresponding to the rawId attribute in
   * the WebAuthn API.
   */
  @NonNull private final ByteArray id;

  /**
   * The authenticator's response to the client’s request to either create a public key credential,
   * or generate an authentication assertion.
   *
   * 

If the {@link PublicKeyCredential} was created in response to * navigator.credentials.create(), this attribute’s value will be an {@link * AuthenticatorAttestationResponse}, otherwise, the {@link PublicKeyCredential} was created in * response to navigator.credentials.get(), and this attribute’s value will be an * {@link AuthenticatorAssertionResponse}. */ @NonNull private final A response; private final AuthenticatorAttachment authenticatorAttachment; /** * A map containing extension identifier → client extension output entries produced by the * extension’s client extension processing. */ @NonNull private final B clientExtensionResults; /** The {@link PublicKeyCredential}'s type value is the string "public-key". */ @NonNull @Builder.Default private final PublicKeyCredentialType type = PublicKeyCredentialType.PUBLIC_KEY; @JsonCreator private PublicKeyCredential( @JsonProperty("id") ByteArray id, @JsonProperty("rawId") ByteArray rawId, @NonNull @JsonProperty("response") A response, @JsonProperty("authenticatorAttachment") AuthenticatorAttachment authenticatorAttachment, @NonNull @JsonProperty("clientExtensionResults") B clientExtensionResults, @NonNull @JsonProperty("type") PublicKeyCredentialType type) { if (id == null && rawId == null) { throw new NullPointerException("At least one of \"id\" and \"rawId\" must be non-null."); } if (id != null && rawId != null && !id.equals(rawId)) { throw new IllegalArgumentException( String.format("\"id\" and \"rawId\" are not equal: %s != %s", id, rawId)); } this.id = id == null ? rawId : id; this.response = response; this.authenticatorAttachment = authenticatorAttachment; this.clientExtensionResults = clientExtensionResults; this.type = type; } private PublicKeyCredential( ByteArray id, @NonNull A response, AuthenticatorAttachment authenticatorAttachment, @NonNull B clientExtensionResults, @NonNull PublicKeyCredentialType type) { this(id, null, response, authenticatorAttachment, clientExtensionResults, type); } /** * The authenticator * attachment modality in effect at the time the credential was created or used. * *

If parsed from JSON, this will be present if and only if the input was a valid value of * {@link AuthenticatorAttachment}. * *

The same value will also be available via {@link * RegistrationResult#getAuthenticatorAttachment()} or {@link * AssertionResult#getAuthenticatorAttachment()} on the result from {@link * RelyingParty#finishRegistration(FinishRegistrationOptions)} or {@link * RelyingParty#finishAssertion(FinishAssertionOptions)}. * * @see RegistrationResult#getAuthenticatorAttachment() * @see AssertionResult#getAuthenticatorAttachment() * @deprecated EXPERIMENTAL: This feature is from a not yet mature standard; it could change as * the standard matures. */ @Deprecated public Optional getAuthenticatorAttachment() { return Optional.ofNullable(authenticatorAttachment); } public static PublicKeyCredentialBuilder.MandatoryStages builder() { return new PublicKeyCredentialBuilder().start(); } public static class PublicKeyCredentialBuilder< A extends AuthenticatorResponse, B extends ClientExtensionOutputs> { private MandatoryStages start() { return new MandatoryStages(this); } @AllArgsConstructor public class MandatoryStages { private final PublicKeyCredentialBuilder builder; /** * {@link PublicKeyCredentialBuilder#id(ByteArray) id} is a required parameter. * * @see PublicKeyCredentialBuilder#id(ByteArray) */ public Step2 id(ByteArray id) { builder.id(id); return new Step2(); } public class Step2 { /** * {@link PublicKeyCredentialBuilder#response(AuthenticatorResponse) response} is a required * parameter. * * @see PublicKeyCredentialBuilder#response(AuthenticatorResponse) */ public Step3 response(A response) { builder.response(response); return new Step3(); } } public class Step3 { /** * {@link PublicKeyCredentialBuilder#clientExtensionResults(ClientExtensionOutputs) * clientExtensionResults} is a required parameter. * * @see PublicKeyCredentialBuilder#clientExtensionResults(ClientExtensionOutputs) */ public PublicKeyCredentialBuilder clientExtensionResults(B clientExtensionResults) { return builder.clientExtensionResults(clientExtensionResults); } } } } /** * Parse a {@link PublicKeyCredential} object from JSON. * *

The json should be of the following format: * *

   * {
   *   "id": "(resp.id)",
   *   "response": {
   *     "attestationObject": "(Base64Url encoded resp.attestationObject)",
   *     "clientDataJSON": "(Base64Url encoded resp.clientDataJSON)"
   *   },
   *   "clientExtensionResults": { (resp.getClientExtensionResults()) },
   *   "type": "public-key"
   * }
   * 
* *
*
resp: *
The PublicKeyCredential * object returned from a registration ceremony. *
id: *
The string value of resp.id *
response.attestationObject: *
The value of resp.attestationObject, Base64Url encoded as a string *
response.clientDataJSON: *
The value of resp.clientDataJSON, Base64Url encoded as a string *
clientExtensionResults: *
The return value of resp.getClientExtensionResults() *
type: *
The literal string value "public-key" *
* * @param json a JSON string of the above format * @throws IOException if the json is invalid or cannot be decoded as a {@link * PublicKeyCredential} */ public static PublicKeyCredential< AuthenticatorAttestationResponse, ClientRegistrationExtensionOutputs> parseRegistrationResponseJson(String json) throws IOException { return JacksonCodecs.json() .readValue( json, new TypeReference< PublicKeyCredential< AuthenticatorAttestationResponse, ClientRegistrationExtensionOutputs>>() {}); } /** * Parse a {@link PublicKeyCredential} object from JSON. * *

The json should be of the following format: * *

   * {
   *   "id": "(resp.id)",
   *   "response": {
   *     "authenticatorData": "(Base64Url encoded resp.authenticatorData)",
   *     "signature": "(Base64Url encoded resp.signature)",
   *     "clientDataJSON": "(Base64Url encoded resp.clientDataJSON)",
   *     "userHandle": "(null, undefined or Base64Url encoded resp.userHandle)"
   *   },
   *   "clientExtensionResults": { (resp.getClientExtensionResults()) },
   *   "type": "public-key"
   * }
   * 
* *
*
resp: *
The PublicKeyCredential * object returned from an authentication ceremony. *
id: *
The string value of resp.id *
response.authenticatorData: *
The value of resp.authenticatorData, Base64Url encoded as a string *
response.signature: *
The value of resp.signature, Base64Url encoded as a string *
response.clientDataJSON: *
The value of resp.clientDataJSON, Base64Url encoded as a string *
response.userHandle: *
The value of resp.userHandle Base64Url encoded as a string if present, * otherwise null or undefined *
clientExtensionResults: *
The return value of resp.getClientExtensionResults() *
type: *
The literal string value "public-key" *
* * @param json a JSON string of the above format * @throws IOException if the json is invalid or cannot be decoded as a {@link * PublicKeyCredential} */ public static PublicKeyCredential parseAssertionResponseJson(String json) throws IOException { return JacksonCodecs.json() .readValue( json, new TypeReference< PublicKeyCredential< AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>>() {}); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy