public RawMessage handleCborRequest(ChannelId channelId, byte[] payload) {
		if (payload.length == 0) {
			return RawMessage.error(channelId, HidError.INVALID_LEN);
		}
		Ctap2Method method = Ctap2Method.from(payload[0]);
		byte[] params = new byte[payload.length - 1];
		System.arraycopy(payload, 1, params, 0, payload.length - 1);
		try {
			log.debug("Received CBOR request with method {} and body {}", method, CborDecoder.decode(params));
		} catch (CborException e) {
			log.error("Unable to deserialize CBOR parameters", e);
			return failure(channelId, Ctap2ResponseCode.INVALID_CBOR);
		}
		try {
			switch (method) {
			case GET_ASSERTION:
				GetAssertionRequest gar = GetAssertionRequest.fromBytes(params);
				byte[] assertion = authenticator.getAssertion(gar)
						.handleError(err -> asPayload(err, Collections.emptyList()))
						.elseGet(value -> asPayload(Ctap2ResponseCode.OK, value.asCborMap()));
				return ImmutableRawMessage.builder()
						.channelId(channelId)
						.command(HidCommand.CBOR)
						.payload(assertion)
						.build();
			case GET_INFO:
				GetInfoResponse response = authenticator.getInfo();
				log.trace("Authenticator supports options {}", response);
				byte[] info = asPayload(Ctap2ResponseCode.OK, response.asCborMap());
				return ImmutableRawMessage.builder()
						.channelId(channelId)
						.command(HidCommand.CBOR)
						.payload(info)
						.build();
			case MAKE_CREDENTIAL:
				MakeCredentialRequest request = MakeCredentialRequest.fromBytes(params);
				Result<MakeCredentialResponse, Ctap2ResponseCode> result = authenticator.makeCredential(request.clientDataHash(),
						request.relayingPartyId(), request.userId(), request.supportedAlgorithmIds(), request.pinAuth());
				byte[] credential = result
						.handleError(err -> asPayload(err, Collections.emptyList()))
						.elseGet(value -> asPayload(Ctap2ResponseCode.OK, value.asCborMap()));
				return ImmutableRawMessage.builder()
						.channelId(channelId)
						.command(HidCommand.CBOR)
						.payload(credential)
						.build();
			case CLIENT_PIN:
				Map pinParams = (Map) CborDecoder.decode(params).get(0);
				UnsignedInteger pinProtocol = (UnsignedInteger) pinParams.get(new UnsignedInteger(0x01));
				// TODO: handle pinProtocol != 1 somehow
				UnsignedInteger subCommand = (UnsignedInteger) pinParams.get(new UnsignedInteger(0x02));
				switch(subCommand.getValue().intValue()) {
				case 0x01: // get retries
					List<DataItem> retries = pinRequestHandler.getRetries();
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(asPayload(Ctap2ResponseCode.OK, retries))
							.build();
				case 0x02: // get key
					List<DataItem> key = pinRequestHandler.getKeyAgreementKey();
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(asPayload(Ctap2ResponseCode.OK, key))
							.build();
				case 0x03: // set pin
					Map hostCoseKey = (Map) pinParams.get(new UnsignedInteger(0x03));
					ByteString pinAuth = (ByteString) pinParams.get(new UnsignedInteger(0x04));
					ByteString newPinEnc = (ByteString) pinParams.get(new UnsignedInteger(0x05));
					Ctap2ResponseCode code = pinRequestHandler.setPin(hostCoseKey, newPinEnc.getBytes(), pinAuth.getBytes());
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(asPayload(code, Collections.emptyList()))
							.build();
				case 0x04: // change pin
					Map hostCoseKey2 = (Map) pinParams.get(new UnsignedInteger(0x03));
					ByteString pinAuth2 = (ByteString) pinParams.get(new UnsignedInteger(0x04));
					ByteString newPinEnc2 = (ByteString) pinParams.get(new UnsignedInteger(0x05));
					ByteString PinHashEnc = (ByteString) pinParams.get(new UnsignedInteger(0x06));
					Ctap2ResponseCode code2 = pinRequestHandler.changePin(hostCoseKey2, PinHashEnc.getBytes(), newPinEnc2.getBytes(), pinAuth2.getBytes());
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(asPayload(code2, Collections.emptyList()))
							.build();
				case 0x05: // get pin token
					Map hostCoseKey3 = (Map) pinParams.get(new UnsignedInteger(0x03));
					ByteString pinHashEnc2 = (ByteString) pinParams.get(new UnsignedInteger(0x06));
					Result<List<DataItem>, Ctap2ResponseCode> pinToken = pinRequestHandler.getPinToken(hostCoseKey3, pinHashEnc2.getBytes());
					byte[] pinTokenPayload = pinToken.handleError(err -> asPayload(err, Collections.emptyList()))
							.elseGet(val -> asPayload(Ctap2ResponseCode.OK, val));
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(pinTokenPayload)
							.build();
				}
				break;
			case RESET:
			case GET_NEXT_ASSERTION:
			default:
				return RawMessage.error(channelId, HidError.INVALID_CMD);
			}
		} catch (CborException e) {
			log.error("Unable to deserialize CBOR", e);
		}
		return failure(channelId, Ctap2ResponseCode.INVALID_CBOR);
	}
public RawMessage handleCborRequest(ChannelId channelId, byte[] payload) {
		if (payload.length == 0) {
			return RawMessage.error(channelId, HidError.INVALID_LEN);
		}
		Ctap2Method method = Ctap2Method.from(payload[0]);
		byte[] params = new byte[payload.length - 1];
		System.arraycopy(payload, 1, params, 0, payload.length - 1);
		try {
			log.debug("Received CBOR request with method {} and body {}", method, CborDecoder.decode(params));
		} catch (CborException e) {
			log.error("Unable to deserialize CBOR parameters", e);
			return failure(channelId, Ctap2ResponseCode.INVALID_CBOR);
		}
		try {
			switch (method) {
			case GET_ASSERTION:
				GetAssertionRequest gar = GetAssertionRequest.fromBytes(params);
				byte[] assertion = authenticator.getAssertion(gar)
						.handleError(err -> asPayload(err, Collections.emptyList()))
						.elseGet(value -> asPayload(Ctap2ResponseCode.OK, value.asCborMap()));
				return ImmutableRawMessage.builder()
						.channelId(channelId)
						.command(HidCommand.CBOR)
						.payload(assertion)
						.build();
			case GET_INFO:
				GetInfoResponse response = authenticator.getInfo();
				log.trace("Authenticator supports options {}", response);
				byte[] info = asPayload(Ctap2ResponseCode.OK, response.asCborMap());
				return ImmutableRawMessage.builder()
						.channelId(channelId)
						.command(HidCommand.CBOR)
						.payload(info)
						.build();
			case MAKE_CREDENTIAL:
				MakeCredentialRequest request = MakeCredentialRequest.fromBytes(params);
				Result<MakeCredentialResponse, Ctap2ResponseCode> result = authenticator.makeCredential(request.clientDataHash(),
						request.relayingPartyId(), request.userId(), request.supportedAlgorithmIds(), request.pinAuth());
				byte[] credential = result
						.handleError(err -> asPayload(err, Collections.emptyList()))
						.elseGet(value -> asPayload(Ctap2ResponseCode.OK, value.asCborMap()));
				return ImmutableRawMessage.builder()
						.channelId(channelId)
						.command(HidCommand.CBOR)
						.payload(credential)
						.build();
			case CLIENT_PIN:
				Map pinParams = (Map) CborDecoder.decode(params).get(0);
				UnsignedInteger pinProtocol = (UnsignedInteger) pinParams.get(new UnsignedInteger(0x01));
			
				UnsignedInteger subCommand = (UnsignedInteger) pinParams.get(new UnsignedInteger(0x02));
				switch(subCommand.getValue().intValue()) {
				case 0x01:
					List<DataItem> retries = pinRequestHandler.getRetries();
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(asPayload(Ctap2ResponseCode.OK, retries))
							.build();
				case 0x02:
					List<DataItem> key = pinRequestHandler.getKeyAgreementKey();
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(asPayload(Ctap2ResponseCode.OK, key))
							.build();
				case 0x03:
					Map hostCoseKey = (Map) pinParams.get(new UnsignedInteger(0x03));
					ByteString pinAuth = (ByteString) pinParams.get(new UnsignedInteger(0x04));
					ByteString newPinEnc = (ByteString) pinParams.get(new UnsignedInteger(0x05));
					Ctap2ResponseCode code = pinRequestHandler.setPin(hostCoseKey, newPinEnc.getBytes(), pinAuth.getBytes());
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(asPayload(code, Collections.emptyList()))
							.build();
				case 0x04:
					Map hostCoseKey2 = (Map) pinParams.get(new UnsignedInteger(0x03));
					ByteString pinAuth2 = (ByteString) pinParams.get(new UnsignedInteger(0x04));
					ByteString newPinEnc2 = (ByteString) pinParams.get(new UnsignedInteger(0x05));
					ByteString PinHashEnc = (ByteString) pinParams.get(new UnsignedInteger(0x06));
					Ctap2ResponseCode code2 = pinRequestHandler.changePin(hostCoseKey2, PinHashEnc.getBytes(), newPinEnc2.getBytes(), pinAuth2.getBytes());
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(asPayload(code2, Collections.emptyList()))
							.build();
				case 0x05:
					Map hostCoseKey3 = (Map) pinParams.get(new UnsignedInteger(0x03));
					ByteString pinHashEnc2 = (ByteString) pinParams.get(new UnsignedInteger(0x06));
					Result<List<DataItem>, Ctap2ResponseCode> pinToken = pinRequestHandler.getPinToken(hostCoseKey3, pinHashEnc2.getBytes());
					byte[] pinTokenPayload = pinToken.handleError(err -> asPayload(err, Collections.emptyList()))
							.elseGet(val -> asPayload(Ctap2ResponseCode.OK, val));
					return ImmutableRawMessage.builder()
							.channelId(channelId)
							.command(HidCommand.CBOR)
							.payload(pinTokenPayload)
							.build();
				}
				break;
			case RESET:
			case GET_NEXT_ASSERTION:
			default:
				return RawMessage.error(channelId, HidError.INVALID_CMD);
			}
		} catch (CborException e) {
			log.error("Unable to deserialize CBOR", e);
		}
		return failure(channelId, Ctap2ResponseCode.INVALID_CBOR);
	}
public rawmessage handlecborrequest(channelid channelid, byte[] payload) { if (payload.length == 0) { return rawmessage.error(channelid, hiderror.invalid_len); } ctap2method method = ctap2method.from(payload[0]); byte[] params = new byte[payload.length - 1]; system.arraycopy(payload, 1, params, 0, payload.length - 1); try { log.debug("received cbor request with method {} and body {}", method, cbordecoder.decode(params)); } catch (cborexception e) { log.error("unable to deserialize cbor parameters", e); return failure(channelid, ctap2responsecode.invalid_cbor); } try { switch (method) { case get_assertion: getassertionrequest gar = getassertionrequest.frombytes(params); byte[] assertion = authenticator.getassertion(gar) .handleerror(err -> aspayload(err, collections.emptylist())) .elseget(value -> aspayload(ctap2responsecode.ok, value.ascbormap())); return immutablerawmessage.builder() .channelid(channelid) .command(hidcommand.cbor) .payload(assertion) .build(); case get_info: getinforesponse response = authenticator.getinfo(); log.trace("authenticator supports options {}", response); byte[] info = aspayload(ctap2responsecode.ok, response.ascbormap()); return immutablerawmessage.builder() .channelid(channelid) .command(hidcommand.cbor) .payload(info) .build(); case make_credential: makecredentialrequest request = makecredentialrequest.frombytes(params); result<makecredentialresponse, ctap2responsecode> result = authenticator.makecredential(request.clientdatahash(), request.relayingpartyid(), request.userid(), request.supportedalgorithmids(), request.pinauth()); byte[] credential = result .handleerror(err -> aspayload(err, collections.emptylist())) .elseget(value -> aspayload(ctap2responsecode.ok, value.ascbormap())); return immutablerawmessage.builder() .channelid(channelid) .command(hidcommand.cbor) .payload(credential) .build(); case client_pin: map pinparams = (map) cbordecoder.decode(params).get(0); unsignedinteger pinprotocol = (unsignedinteger) pinparams.get(new unsignedinteger(0x01)); unsignedinteger subcommand = (unsignedinteger) pinparams.get(new unsignedinteger(0x02)); switch(subcommand.getvalue().intvalue()) { case 0x01: list<dataitem> retries = pinrequesthandler.getretries(); return immutablerawmessage.builder() .channelid(channelid) .command(hidcommand.cbor) .payload(aspayload(ctap2responsecode.ok, retries)) .build(); case 0x02: list<dataitem> key = pinrequesthandler.getkeyagreementkey(); return immutablerawmessage.builder() .channelid(channelid) .command(hidcommand.cbor) .payload(aspayload(ctap2responsecode.ok, key)) .build(); case 0x03: map hostcosekey = (map) pinparams.get(new unsignedinteger(0x03)); bytestring pinauth = (bytestring) pinparams.get(new unsignedinteger(0x04)); bytestring newpinenc = (bytestring) pinparams.get(new unsignedinteger(0x05)); ctap2responsecode code = pinrequesthandler.setpin(hostcosekey, newpinenc.getbytes(), pinauth.getbytes()); return immutablerawmessage.builder() .channelid(channelid) .command(hidcommand.cbor) .payload(aspayload(code, collections.emptylist())) .build(); case 0x04: map hostcosekey2 = (map) pinparams.get(new unsignedinteger(0x03)); bytestring pinauth2 = (bytestring) pinparams.get(new unsignedinteger(0x04)); bytestring newpinenc2 = (bytestring) pinparams.get(new unsignedinteger(0x05)); bytestring pinhashenc = (bytestring) pinparams.get(new unsignedinteger(0x06)); ctap2responsecode code2 = pinrequesthandler.changepin(hostcosekey2, pinhashenc.getbytes(), newpinenc2.getbytes(), pinauth2.getbytes()); return immutablerawmessage.builder() .channelid(channelid) .command(hidcommand.cbor) .payload(aspayload(code2, collections.emptylist())) .build(); case 0x05: map hostcosekey3 = (map) pinparams.get(new unsignedinteger(0x03)); bytestring pinhashenc2 = (bytestring) pinparams.get(new unsignedinteger(0x06)); result<list<dataitem>, ctap2responsecode> pintoken = pinrequesthandler.getpintoken(hostcosekey3, pinhashenc2.getbytes()); byte[] pintokenpayload = pintoken.handleerror(err -> aspayload(err, collections.emptylist())) .elseget(val -> aspayload(ctap2responsecode.ok, val)); return immutablerawmessage.builder() .channelid(channelid) .command(hidcommand.cbor) .payload(pintokenpayload) .build(); } break; case reset: case get_next_assertion: default: return rawmessage.error(channelid, hiderror.invalid_cmd); } } catch (cborexception e) { log.error("unable to deserialize cbor", e); } return failure(channelid, ctap2responsecode.invalid_cbor); }