Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class CredentialsContainer {
private final ObjectMapper mapper;

/**
* Creates a new CredentialsContainer with the specified {@link Origin} and a list of "known" authenticators.
* Creates a new CredentialsContainer with a list of "known" authenticators.
*
* @param authenticators A list of authenticators that are available to this container.
* This list will be queried to create/get WebAuthn credentials.
Expand Down
92 changes: 0 additions & 92 deletions src/main/java/de/adesso/softauthn/Origin.java

This file was deleted.

243 changes: 123 additions & 120 deletions src/main/java/de/adesso/softauthn/PublicKeyCredentialSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,137 +17,140 @@
*/
public class PublicKeyCredentialSource {

private final PublicKeyCredentialType type;
private final OneKey key;
private final String rpId;
private final ByteArray userHandle;
private final PublicKeyCredentialType type;
private final OneKey key;
private final String rpId;
private final ByteArray userHandle;

private ByteArray id;
private ByteArray id;

/**
* Public constructor of this data class.
* <p>Note that the credential id must be {@link #setId(ByteArray) set} after creation.
*
* @param type Type of credential.
* @param privateKey The private key wrapped as a COSE {@link OneKey}.
* @param rpId The <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#relying-party-identifier">relying party identifier</a>
* @param userHandle The user handle of the user this credential belongs to.
*/
public PublicKeyCredentialSource(PublicKeyCredentialType type, OneKey privateKey, String rpId, ByteArray userHandle) {
this.type = type;
this.key = privateKey;
this.rpId = rpId;
this.userHandle = userHandle;
}
/**
* Public constructor of this data class.
* <p>Note that the credential id must be {@link #setId(ByteArray) set} after creation.
*
* @param type Type of credential.
* @param privateKey The private key wrapped as a COSE {@link OneKey}.
* @param rpId The <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#relying-party-identifier">relying party identifier</a>
* @param userHandle The user handle of the user this credential belongs to.
*/
public PublicKeyCredentialSource(PublicKeyCredentialType type, OneKey privateKey, String rpId, ByteArray userHandle) {
this.type = type;
this.key = privateKey;
this.rpId = rpId;
this.userHandle = userHandle;
}

/**
* See {@link #PublicKeyCredentialSource(PublicKeyCredentialType, OneKey, String, ByteArray) constructor} for a description of this field.
*
* @return credential type.
*/
public PublicKeyCredentialType getType() {
return type;
}
/**
* See {@link #PublicKeyCredentialSource(PublicKeyCredentialType, OneKey, String, ByteArray) constructor} for a description of this field.
*
* @return credential type.
*/
public PublicKeyCredentialType getType() {
return type;
}

/**
* See {@link #PublicKeyCredentialSource(PublicKeyCredentialType, OneKey, String, ByteArray) constructor} for a description of this field.
*
* @return the (private) key.
*/
public OneKey getKey() {
return key;
}
/**
* See {@link #PublicKeyCredentialSource(PublicKeyCredentialType, OneKey, String, ByteArray) constructor} for a description of this field.
*
* @return the (private) key.
*/
public OneKey getKey() {
return key;
}

/**
* See {@link #PublicKeyCredentialSource(PublicKeyCredentialType, OneKey, String, ByteArray) constructor} for a description of this field.
*
* @return relying party id.
*/
public String getRpId() {
return rpId;
}
/**
* See {@link #PublicKeyCredentialSource(PublicKeyCredentialType, OneKey, String, ByteArray) constructor} for a description of this field.
*
* @return relying party id.
*/
public String getRpId() {
return rpId;
}

/**
* See {@link #PublicKeyCredentialSource(PublicKeyCredentialType, OneKey, String, ByteArray) constructor} for a description of this field.
*
* @return user handle.
*/
public ByteArray getUserHandle() {
return userHandle;
}
/**
* See {@link #PublicKeyCredentialSource(PublicKeyCredentialType, OneKey, String, ByteArray) constructor} for a description of this field.
*
* @return user handle.
*/
public ByteArray getUserHandle() {
return userHandle;
}

/**
* Encodes this credential source to a byte array so it can be encrypted and used as the credential id for
* <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#server-side-public-key-credential-source">server-side credential storage</a>
*
* @return this credential source serialized as a CBOR map. It can be deserialized again via {@link #deserialize(ByteArray)}.
* @see #deserialize(ByteArray)
* @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#credential-id">Credential ID</a>
*/
public byte[] serialize() {
CBORObject map = CBORObject.NewMap()
.Set("type", type.ordinal())
.Set("key", key.AsCBOR())
.Set("rpId", rpId);
if (userHandle != null) {
map.Set("user", userHandle.getBytes());
/**
* Encodes this credential source to a byte array so it can be encrypted and used as the credential id for
* <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#server-side-public-key-credential-source">server-side credential storage</a>
*
* @return this credential source serialized as a CBOR map. It can be deserialized again via {@link #deserialize(ByteArray)}.
* @see #deserialize(ByteArray)
* @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#credential-id">Credential ID</a>
*/
public byte[] serialize() {
CBORObject map = CBORObject.NewMap()
.Set("type", type.ordinal())
.Set("key", key.AsCBOR())
.Set("rpId", rpId)
.Set("id", id.getBytes());
if (userHandle != null) {
map.Set("user", userHandle.getBytes());
}
return map.EncodeToBytes();
}
return map.EncodeToBytes();
}

/**
* Deserialize the given byte array to reconstruct the credential source it represents.
*
* @param credentialId The byte array used as a credential id that encodes the credential source data.
* @return An optional containing the resulting credential source if the byte array is indeed a serialized credential
* source, or the empty optional if no credential source can be constructed from the information in the byte array.
*/
public static Optional<PublicKeyCredentialSource> deserialize(ByteArray credentialId) {
try {
CBORObject map = CBORObject.DecodeFromBytes(credentialId.getBytes());
PublicKeyCredentialType type = PublicKeyCredentialType.values()[map.get("type").AsInt32()];
OneKey key = new OneKey(map.get("key"));
String rpId = map.get("rpId").AsString();
CBORObject encodedUserHandle = map.get("user");
ByteArray userHandle = null;
if (encodedUserHandle != null) {
userHandle = new ByteArray(encodedUserHandle.GetByteString());
}
PublicKeyCredentialSource source = new PublicKeyCredentialSource(type, key, rpId, userHandle);
source.setId(credentialId);
return Optional.of(source);
} catch (CBORException | CoseException e) {
return Optional.empty();
/**
* Deserialize the given byte array to reconstruct the credential source it represents.
*
* @param credentialId The byte array used as a credential id that encodes the credential source data.
* @return An optional containing the resulting credential source if the byte array is indeed a serialized credential
* source, or the empty optional if no credential source can be constructed from the information in the byte array.
*/
public static Optional<PublicKeyCredentialSource> deserialize(ByteArray credentialId) {
try {
CBORObject map = CBORObject.DecodeFromBytes(credentialId.getBytes());
PublicKeyCredentialType type = PublicKeyCredentialType.values()[map.get("type").AsInt32()];
OneKey key = new OneKey(map.get("key"));
String rpId = map.get("rpId").AsString();
ByteArray id = new ByteArray(map.get("id").GetByteString());
CBORObject encodedUserHandle = map.get("user");
ByteArray userHandle = null;
if (encodedUserHandle != null) {
userHandle = new ByteArray(encodedUserHandle.GetByteString());
}
PublicKeyCredentialSource source = new PublicKeyCredentialSource(type, key, rpId, userHandle);
source.setId(id);
return Optional.of(source);
} catch (CBORException | CoseException e) {
return Optional.empty();
}
}
}

@Override
public String toString() {
return "PublicKeyCredentialSource{" +
"type=" + type +
", privateKey=" + key +
", rpId='" + rpId + '\'' +
", userHandle=" + userHandle +
'}';
}
@Override
public String toString() {
return "PublicKeyCredentialSource{" +
"type=" + type +
", id=" + id +
", privateKey=" + key +
", rpId='" + rpId + '\'' +
", userHandle=" + userHandle +
'}';
}

/**
* Returns the credential id if set, otherwise null.
*
* @return the credential ID of this credential source.
*/
public ByteArray getId() {
return id;
}
/**
* Returns the credential id if set, otherwise null.
*
* @return the credential ID of this credential source.
*/
public ByteArray getId() {
return id;
}

/**
* Set the credential ID, for example to the {@link #serialize() serialized version of this credential source itself}
* for server-side credentials or a randomly generated byte array for client-side discoverable credentials.
*
* @param id The id to set.
* @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#credential-id">Credential ID</a>
*/
public void setId(ByteArray id) {
this.id = id;
}
/**
* Set the credential ID, for example to the {@link #serialize() serialized version of this credential source itself}
* for server-side credentials or a randomly generated byte array for client-side discoverable credentials.
*
* @param id The id to set.
* @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#credential-id">Credential ID</a>
*/
public void setId(ByteArray id) {
this.id = id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import com.yubico.webauthn.data.exception.Base64UrlException;
import de.adesso.softauthn.Authenticator;
import de.adesso.softauthn.CredentialsContainer;
import de.adesso.softauthn.Origin;
import de.adesso.softauthn.PublicKeyCredentialSource;
import de.adesso.softauthn.authenticator.WebAuthnAuthenticator;
import de.adesso.softauthn.counter.PerCredentialSignatureCounter;
Expand All @@ -20,8 +19,6 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;

public class CredentialsDeserializer extends StdDeserializer<CredentialsContainer> {
Expand Down Expand Up @@ -85,13 +82,6 @@ public CredentialsContainer deserialize(JsonParser p, DeserializationContext ctx
final var signatureCounter = new PerCredentialSignatureCounter();
storedSources.forEach((key, value) -> signatureCounter.increment(value.getId()));

final var credentialSelection = new Function<Set<PublicKeyCredentialSource>, PublicKeyCredentialSource>() {
@Override
public PublicKeyCredentialSource apply(Set<PublicKeyCredentialSource> publicKeyCredentialSources) {
return null;
}
};

final var webauth = WebAuthnAuthenticator.builder()
.aaguid(aaguid.getBytes())
.attachment(attachment)
Expand Down
Loading