Skip to content

Commit

Permalink
add serializeBytes and deserializeBytes methods
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamVe committed Oct 4, 2023
1 parent 4711149 commit 61888bf
Show file tree
Hide file tree
Showing 15 changed files with 151 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ protected Ctap2Session.CredentialData ctapMakeCredential(
@Nullable CommandState state
) throws IOException, CommandException, ClientError {

final SerializationType serializationType = SerializationType.CBOR;

byte[] pinToken = null;
try {
if (options.getExtensions() != null) {
Expand All @@ -347,7 +349,7 @@ protected Ctap2Session.CredentialData ctapMakeCredential(
"Extensions not supported");
}

Map<String, ?> rp = options.getRp().toMap();
Map<String, ?> rp = options.getRp().toMap(serializationType);
String rpId = options.getRp().getId();
if (rpId == null) {
((Map<String, Object>) rp).put("id", effectiveDomain);
Expand Down Expand Up @@ -394,12 +396,12 @@ protected Ctap2Session.CredentialData ctapMakeCredential(
options.getExcludeCredentials()
);

final Map<String, ?> user = options.getUser().toMap(SerializationType.CBOR);
final Map<String, ?> user = options.getUser().toMap(serializationType);

List<Map<String, ?>> pubKeyCredParams = new ArrayList<>();
for (PublicKeyCredentialParameters param : options.getPubKeyCredParams()) {
if (isPublicKeyCredentialTypeSupported(param.getType())) {
pubKeyCredParams.add(param.toMap());
pubKeyCredParams.add(param.toMap(serializationType));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

package com.yubico.yubikit.fido.webauthn;

import com.yubico.yubikit.core.internal.codec.Base64;
import static com.yubico.yubikit.fido.webauthn.SerializationUtils.deserializeBytes;
import static com.yubico.yubikit.fido.webauthn.SerializationUtils.serializeBytes;

import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -63,54 +64,24 @@ public byte[] getUserHandle() {
@Override
public Map<String, ?> toMap(SerializationType serializationType) {
Map<String, Object> map = new HashMap<>();
switch (serializationType) {
case JSON: {
map.put(CLIENT_DATA_JSON, Base64.encode(getClientDataJson()));
map.put(AUTHENTICATOR_DATA, Base64.encode(authenticatorData));
map.put(SIGNATURE, Base64.encode(signature));
if (userHandle != null) {
map.put(USER_HANDLE, Base64.encode(userHandle));
}
break;
}
case CBOR: {
map.put(CLIENT_DATA_JSON, getClientDataJson());
map.put(AUTHENTICATOR_DATA, authenticatorData);
map.put(SIGNATURE, signature);
if (userHandle != null) {
map.put(USER_HANDLE, userHandle);
}
break;
}
map.put(CLIENT_DATA_JSON, serializeBytes(getClientDataJson(), serializationType));
map.put(AUTHENTICATOR_DATA, serializeBytes(authenticatorData, serializationType));
map.put(SIGNATURE, serializeBytes(signature, serializationType));
if (userHandle != null) {
map.put(USER_HANDLE, serializeBytes(userHandle, serializationType));
}
return map;
}

public Map<String, ?> toMap() {
return toMap(SerializationType.DEFAULT);
}

public static AuthenticatorAssertionResponse fromMap(
Map<String, ?> map,
SerializationType serializationType
) {
return new AuthenticatorAssertionResponse(
serializationType == SerializationType.JSON
? Base64.decode(Objects.requireNonNull((String) map.get(CLIENT_DATA_JSON)))
: Objects.requireNonNull((byte[]) map.get(CLIENT_DATA_JSON)),
serializationType == SerializationType.JSON
? Base64.decode(Objects.requireNonNull((String) map.get(AUTHENTICATOR_DATA)))
: Objects.requireNonNull((byte[]) map.get(AUTHENTICATOR_DATA)),
serializationType == SerializationType.JSON
? Base64.decode(Objects.requireNonNull((String) map.get(SIGNATURE)))
: Objects.requireNonNull((byte[]) map.get(SIGNATURE)),
serializationType == SerializationType.JSON
? Base64.decode((String) map.get(USER_HANDLE))
: (byte[]) map.get(USER_HANDLE));
}

public static AuthenticatorAssertionResponse fromMap(Map<String, ?> map) {
return fromMap(map, SerializationType.DEFAULT);
deserializeBytes(Objects.requireNonNull(map.get(CLIENT_DATA_JSON)), serializationType),
deserializeBytes(Objects.requireNonNull(map.get(AUTHENTICATOR_DATA)), serializationType),
deserializeBytes(Objects.requireNonNull(map.get(SIGNATURE)), serializationType),
deserializeBytes(Objects.requireNonNull(map.get(USER_HANDLE)), serializationType));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

package com.yubico.yubikit.fido.webauthn;

import static com.yubico.yubikit.fido.webauthn.SerializationUtils.deserializeBytes;
import static com.yubico.yubikit.fido.webauthn.SerializationUtils.serializeBytes;

import com.yubico.yubikit.core.internal.Logger;
import com.yubico.yubikit.core.internal.codec.Base64;
import com.yubico.yubikit.fido.Cose;

import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -130,65 +132,32 @@ public byte[] getAttestationObject() {
@Override
public Map<String, ?> toMap(SerializationType serializationType) {
Map<String, Object> map = new HashMap<>();
switch (serializationType) {
case JSON: {
map.put(CLIENT_DATA_JSON, Base64.encode(getClientDataJson()));
map.put(AUTHENTICATOR_DATA, Base64.encode(authenticatorData.getBytes()));
map.put(TRANSPORTS, transports);
if (publicKey != null) {
map.put(PUBLIC_KEY, Base64.encode(publicKey));
}
map.put(PUBLIC_KEY_ALGORITHM, publicKeyAlgorithm);
map.put(ATTESTATION_OBJECT, Base64.encode(attestationObject));
break;
}
case CBOR: {
map.put(CLIENT_DATA_JSON, getClientDataJson());
map.put(AUTHENTICATOR_DATA, authenticatorData.getBytes());
map.put(TRANSPORTS, transports);
if (publicKey != null) {
map.put(PUBLIC_KEY, publicKey);
}
map.put(PUBLIC_KEY_ALGORITHM, publicKeyAlgorithm);
map.put(ATTESTATION_OBJECT, attestationObject);
break;
}
map.put(CLIENT_DATA_JSON, serializeBytes(getClientDataJson(), serializationType));
map.put(AUTHENTICATOR_DATA, serializeBytes(authenticatorData.getBytes(), serializationType));
map.put(TRANSPORTS, transports);
if (publicKey != null) {
map.put(PUBLIC_KEY, serializeBytes(publicKey, serializationType));
}
map.put(PUBLIC_KEY_ALGORITHM, publicKeyAlgorithm);
map.put(ATTESTATION_OBJECT, serializeBytes(attestationObject, serializationType));
return map;
}

public Map<String, ?> toMap() {
return toMap(SerializationType.DEFAULT);
}

@SuppressWarnings("unchecked")
public static AuthenticatorAttestationResponse fromMap(Map<String, ?> map, SerializationType serializationType) {
Object publicKey = serializationType == SerializationType.JSON
? (String) map.get(PUBLIC_KEY)
: (byte[]) map.get(PUBLIC_KEY);
Object publicKey = map.get(PUBLIC_KEY);
return new AuthenticatorAttestationResponse(
serializationType == SerializationType.JSON
? Base64.decode(Objects.requireNonNull((String) map.get(CLIENT_DATA_JSON)))
: Objects.requireNonNull((byte[]) map.get(CLIENT_DATA_JSON)),
AuthenticatorData.parseFrom(ByteBuffer.wrap(
serializationType == SerializationType.JSON
? Base64.decode((String) map.get(AUTHENTICATOR_DATA))
: (byte[]) map.get(AUTHENTICATOR_DATA))),
deserializeBytes(Objects.requireNonNull(map.get(CLIENT_DATA_JSON)), serializationType),
AuthenticatorData.parseFrom(
ByteBuffer.wrap(
deserializeBytes(map.get(AUTHENTICATOR_DATA), serializationType))),
(List<String>) Objects.requireNonNull(map.get(TRANSPORTS)),
publicKey == null ? null : serializationType == SerializationType.JSON
? Base64.decode((String) publicKey)
: (byte[]) publicKey,
publicKey == null ? null : deserializeBytes(publicKey, serializationType),
(Integer) map.get(PUBLIC_KEY_ALGORITHM),
serializationType == SerializationType.JSON
? Base64.decode(Objects.requireNonNull((String) map.get(ATTESTATION_OBJECT)))
: Objects.requireNonNull((byte[]) map.get(ATTESTATION_OBJECT))
deserializeBytes(Objects.requireNonNull(map.get(ATTESTATION_OBJECT)), serializationType)
);
}

public static AuthenticatorAttestationResponse fromMap(Map<String, ?> map) {
return fromMap(map, SerializationType.DEFAULT);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public String getUserVerification() {
return userVerification;
}

public Map<String, ?> toMap() {
public Map<String, ?> toMap(@SuppressWarnings("unused") SerializationType serializationType) {
Map<String, Object> map = new HashMap<>();
if (authenticatorAttachment != null) {
map.put(AUTHENTICATOR_ATTACHMENT, authenticatorAttachment);
Expand All @@ -73,7 +73,9 @@ public String getUserVerification() {
return map;
}

public static AuthenticatorSelectionCriteria fromMap(Map<String, ?> map) {
public static AuthenticatorSelectionCriteria fromMap(
Map<String, ?> map,
@SuppressWarnings("unused") SerializationType serializationType) {
String residentKeyRequirement = (String) map.get(RESIDENT_KEY);
if (residentKeyRequirement == null) {
// Backwards compatibility with WebAuthn level 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.yubico.yubikit.fido.webauthn;

import static com.yubico.yubikit.fido.webauthn.SerializationUtils.serializeBytes;

import com.yubico.yubikit.core.internal.codec.Base64;

import com.yubico.yubikit.fido.ctap.Ctap2Session;
Expand Down Expand Up @@ -78,15 +80,7 @@ public AuthenticatorResponse getResponse() {
Map<String, Object> map = new HashMap<>();
map.put(ID, getId());
map.put(TYPE, getType());
switch (serializationType) {
case CBOR:
map.put(RAW_ID, getRawId());
break;
case JSON:
map.put(RAW_ID, Base64.encode(getRawId()));
break;
}

map.put(RAW_ID, serializeBytes(getRawId(), serializationType));
map.put(AUTHENTICATOR_ATTACHMENT, AuthenticatorAttachment.CROSS_PLATFORM);
map.put(RESPONSE, getResponse().toMap(serializationType));
return map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

package com.yubico.yubikit.fido.webauthn;

import com.yubico.yubikit.core.internal.codec.Base64;
import static com.yubico.yubikit.fido.webauthn.SerializationUtils.deserializeBytes;
import static com.yubico.yubikit.fido.webauthn.SerializationUtils.serializeBytes;

import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -114,19 +115,12 @@ public Extensions getExtensions() {

public Map<String, ?> toMap(SerializationType serializationType) {
Map<String, Object> map = new HashMap<>();
map.put(RP, rp.toMap());
map.put(RP, rp.toMap(serializationType));
map.put(USER, user.toMap(serializationType));
switch (serializationType) {
case JSON:
map.put(CHALLENGE, Base64.encode(challenge));
break;
case CBOR:
map.put(CHALLENGE, challenge);
break;
}
map.put(CHALLENGE, serializeBytes(challenge, serializationType));
List<Map<String, ?>> paramsList = new ArrayList<>();
for (PublicKeyCredentialParameters params : pubKeyCredParams) {
paramsList.add(params.toMap());
paramsList.add(params.toMap(serializationType));
}
map.put(PUB_KEY_CRED_PARAMS, paramsList);
if (timeout != null) {
Expand All @@ -140,7 +134,7 @@ public Extensions getExtensions() {
map.put(EXCLUDE_CREDENTIALS, excludeCredentialsList);
}
if (authenticatorSelection != null) {
map.put(AUTHENTICATOR_SELECTION, authenticatorSelection.toMap());
map.put(AUTHENTICATOR_SELECTION, authenticatorSelection.toMap(serializationType));
}
map.put(ATTESTATION, attestation);
if (extensions != null) {
Expand All @@ -154,10 +148,13 @@ public Extensions getExtensions() {
}

@SuppressWarnings("unchecked")
public static PublicKeyCredentialCreationOptions fromMap(Map<String, ?> map, SerializationType serializationType) {
public static PublicKeyCredentialCreationOptions fromMap(
Map<String, ?> map,
SerializationType serializationType) {
List<PublicKeyCredentialParameters> pubKeyCredParams = new ArrayList<>();
for (Map<String, ?> params : Objects.requireNonNull((List<Map<String, ?>>) map.get(PUB_KEY_CRED_PARAMS))) {
pubKeyCredParams.add(PublicKeyCredentialParameters.fromMap(params));
for (Map<String, ?> params :
Objects.requireNonNull((List<Map<String, ?>>) map.get(PUB_KEY_CRED_PARAMS))) {
pubKeyCredParams.add(PublicKeyCredentialParameters.fromMap(params, serializationType));
}
List<PublicKeyCredentialDescriptor> excludeCredentials = null;
List<Map<String, ?>> excludeCredentialsList = (List<Map<String, ?>>) map.get(EXCLUDE_CREDENTIALS);
Expand All @@ -172,15 +169,19 @@ public static PublicKeyCredentialCreationOptions fromMap(Map<String, ?> map, Ser
Number timeout = (Number) map.get(TIMEOUT);

return new PublicKeyCredentialCreationOptions(
PublicKeyCredentialRpEntity.fromMap(Objects.requireNonNull((Map<String, ?>) map.get(RP))),
PublicKeyCredentialUserEntity.fromMap(Objects.requireNonNull((Map<String, ?>) map.get(USER)), serializationType),
serializationType == SerializationType.JSON
? Base64.decode(Objects.requireNonNull((String) map.get(CHALLENGE)))
: Objects.requireNonNull((byte[]) map.get(CHALLENGE)),
PublicKeyCredentialRpEntity.fromMap(
Objects.requireNonNull((Map<String, ?>) map.get(RP)),
serializationType),
PublicKeyCredentialUserEntity.fromMap(
Objects.requireNonNull((Map<String, ?>) map.get(USER)),
serializationType),
deserializeBytes(Objects.requireNonNull(map.get(CHALLENGE)), serializationType),
pubKeyCredParams,
timeout == null ? null : timeout.longValue(),
excludeCredentials,
authenticatorSelection == null ? null : AuthenticatorSelectionCriteria.fromMap(authenticatorSelection),
authenticatorSelection == null ? null : AuthenticatorSelectionCriteria.fromMap(
authenticatorSelection,
serializationType),
(String) map.get(ATTESTATION),
null // Extensions currently ignored
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

package com.yubico.yubikit.fido.webauthn;

import com.yubico.yubikit.core.internal.codec.Base64;
import static com.yubico.yubikit.fido.webauthn.SerializationUtils.deserializeBytes;
import static com.yubico.yubikit.fido.webauthn.SerializationUtils.serializeBytes;

import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -64,40 +65,22 @@ public List<String> getTransports() {
public Map<String, ?> toMap(SerializationType serializationType) {
Map<String, Object> map = new HashMap<>();
map.put(TYPE, type);
switch (serializationType) {
case JSON:
map.put(ID, Base64.encode(id));
break;
case CBOR:
map.put(ID, id);
break;
}
map.put(ID, serializeBytes(id, serializationType));
if (transports != null) {
map.put(TRANSPORTS, transports);
}
return map;
}

public Map<String, ?> toMap() {
return toMap(SerializationType.DEFAULT);
}

@SuppressWarnings("unchecked")
public static PublicKeyCredentialDescriptor fromMap(
Map<String, ?> map,
SerializationType serializationType
) {
return new PublicKeyCredentialDescriptor(
Objects.requireNonNull((String) map.get(TYPE)),
serializationType == SerializationType.JSON
? Base64.decode(Objects.requireNonNull((String) map.get(ID)))
: Objects.requireNonNull((byte[]) map.get(ID)),
(List<String>) map.get(TRANSPORTS)
);
}

public static PublicKeyCredentialDescriptor fromMap(Map<String, ?> map) {
return fromMap(map, SerializationType.DEFAULT);
deserializeBytes(Objects.requireNonNull(map.get(ID)), serializationType),
(List<String>) map.get(TRANSPORTS));
}

@Override
Expand Down
Loading

0 comments on commit 61888bf

Please sign in to comment.