Skip to content

Could decoding be more ergonomic? #127

Description

@jhannes

I'm trying to use cbor-java to implement webauth. In this case, I need to get a COSE from a subset of a binary field in a CBOR object. The code for doing this with cbor-java could be more ergonomic:

Map attestationDataItem = (Map) CborDecoder.decode(Base64.getDecoder().decode(base64AttestationObject)).get(0);
byte[] authData = ((ByteString) attestationDataItem.get(new UnicodeString("authData"))).getBytes();
int idLength = authData[53] << 8 | authData[54];
byte[] publicKeyBytes = new byte[authData.length - 55 - idLength];

Map cosePublicKey = (Map) CborDecoder.decode(publicKeyBytes).get(0);

Number keyType = (Number) cosePublicKey.get(new UnsignedInteger(1));
KeyFactory keyFactory = KeyFactory.getInstance("EC"); // since keyType == 2

Number algorithm = (Number) cosePublicKey.get(new UnsignedInteger(3));

Number curveType = (Number) cosePublicKey.get(new UnsignedInteger(-1));
AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
params.init(new ECGenParameterSpec("secp256k1")); // since curveType == -1

// since keyType == 2
byte[] x = ((ByteString) cosePublicKey.get(new UnsignedInteger(-2))).getBytes();
byte[] y = ((ByteString) cosePublicKey.get(new UnsignedInteger(-3))).getBytes();

ECPublicKeySpec keySpec = new ECPublicKeySpec(
        new ECPoint(new BigInteger(x), new BigInteger(y)),
        params.getParameterSpec(ECParameterSpec.class)
);

(please disregard the KeyFactory, AlgorithmParameters and ECGenParameterSpec stuff - this is java.security stuff)

In an ideal world, I would be able to write something like:

Map attestationDataItem = CborDecoder.decodeMap(Base64.getDecoder().decode(base64AttestationObject)).get(0);
byte[] authData = attestationDataItem.getBytes("authData");
int idLength = authData[53] << 8 | authData[54];
byte[] publicKeyBytes = new byte[authData.length - 55 - idLength];

Map cosePublicKey = CborDecoder.decodeMap(publicKeyBytes).get(0);

int keyType = cosePublicKey.getInt(1);
KeyFactory keyFactory = KeyFactory.getInstance("EC"); // since keyType == 2

int algorithm = cosePublicKey.getInt(3);

int curveType = cosePublicKey.getInt(-1);
AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
params.init(new ECGenParameterSpec("secp256k1")); // since curveType == -1

// since keyType == 2
byte[] x = cosePublicKey.getBytes(-2);
byte[] y = cosePublicKey.getBytes(-3);

Would you consider a pull request to this effect?

(If you want to be really ambitious, doing COSE => java.security would be cool)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions