size_t buffSize = 73; // epoch is int64 which may take up to 8B (9B with key) in CBOR
size_t mapElements = 6;
- CborEncoder encoder, mapEncoder;
- CborError err = CborNoError;
CryptoBuffer buffer(buffSize, 0);
assert(publicKey.size() <= 33);
buffer.resize(buffSize);
}
- cbor_encoder_init(&encoder, buffer.data(), buffer.size(), 0);
- if ((err = cbor_encoder_create_map(&encoder, &mapEncoder, mapElements))) {
- LogError("cbor_encoder_create_map error");
- throw EncodingFailed{};
- }
-
- // key 0 - public key
- if ((err = cbor_encode_int(&mapEncoder, 0))) {
- LogError("cbor_encode_int error in public key encoding");
- throw EncodingFailed{};
- }
-
- if ((err = cbor_encode_byte_string(&mapEncoder, publicKey.data(), publicKey.size()))) {
- LogError("cbor_encode_byte_string error in public key encoding");
- throw EncodingFailed{};
- }
-
- // key 1 - QR Secret
- if ((err = cbor_encode_int(&mapEncoder, 1))) {
- LogError("cbor_encode_int error in QR secret encoding");
- throw EncodingFailed{};
- }
-
- if ((err = cbor_encode_byte_string(&mapEncoder, qrSecret.data(), qrSecret.size()))) {
- LogError("cbor_encode_byte_string error in QR secret encoding");
- throw EncodingFailed{};
- }
-
- // key 2 - assigned tunnel servers domains
- if ((err = cbor_encode_int(&mapEncoder, 2))) {
- LogError("cbor_encode_int error in tunnel servers domains encoding");
- throw EncodingFailed{};
- }
-
- if ((err = cbor_encode_int(&mapEncoder, ASSIGNED_TUNNEL_SERVER_DOMAINS.size()))) {
- LogError("cbor_encode_int error in tunnel servers domains encoding");
- throw EncodingFailed{};
- }
-
- // key 3 - current time
- if ((err = cbor_encode_int(&mapEncoder, 3))) {
- LogError("cbor_encode_int error in time encoding");
- throw EncodingFailed{};
- }
-
- if ((err = cbor_encode_int(&mapEncoder, getEpoch()))) {
- LogError("cbor_encode_int error in time encoding");
- throw EncodingFailed{};
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(mapElements);
+ // key 0 - public key
+ map.AppendByteStringAt(0, publicKey);
+ // key 1 - QR Secret
+ map.AppendByteStringAt(1, qrSecret);
+ // key 2 - assigned tunnel servers domains
+ map.AppendInt64At(2, ASSIGNED_TUNNEL_SERVER_DOMAINS.size());
+ // key 3 - current time
+ map.AppendInt64At(3, getEpoch());
+ // key 4 - state assisted transactions
+ map.AppendBooleanAt(4, stateAssisted);
+ // key 5 - "ga" if get assertion and "mc" if make credential
+ // Here specification says byte string with which Android does not work. webauthn.io uses
+ // text
+ map.AppendTextStringAt(5, std::string_view(hint.data(), hint.size()));
+ // key 6 - when GREASE is true
+ if (extraKey)
+ map.AppendInt64At(65535, 0);
}
- // key 4 - state assisted transactions
- if ((err = cbor_encode_int(&mapEncoder, 4))) {
- LogError("cbor_encode_int error in state assisted transactions encoding");
- throw EncodingFailed{};
- }
-
- if ((err = cbor_encode_boolean(&mapEncoder, stateAssisted))) {
- LogError("cbor_encode_boolean error in state assisted transactions encoding");
- throw EncodingFailed{};
- }
-
- // key 5 - "ga" if get assertion and "mc" if make credential
- if ((err = cbor_encode_int(&mapEncoder, 5))) {
- LogError("cbor_encode_int error in hint encoding");
- throw EncodingFailed{};
- }
-
- // Here specification says byte string with which Android does not work. webauthn.io uses text
- // string which works.
- if ((err = cbor_encode_text_string(&mapEncoder, hint.data(), hint.size()))) {
- LogError("cbor_encode_text_string error in hint encoding");
- throw EncodingFailed{};
- }
-
- // key 6 - when GREASE is true
- if (extraKey) {
- if ((err = cbor_encode_int(&mapEncoder, 65535))) {
- LogError("cbor_encode_int error in GREASE");
- throw EncodingFailed{};
- }
- if ((err = cbor_encode_int(&mapEncoder, 0))) {
- LogError("cbor_encode_int error in GREASE");
- throw EncodingFailed{};
- }
- }
-
- if ((err = cbor_encoder_close_container(&encoder, &mapEncoder))) {
- LogError("Cbor encode error: cannot close container");
- throw EncodingFailed{};
- }
-
- buffSize = cbor_encoder_get_buffer_size(&encoder, buffer.data());
- buffer.resize(buffSize);
-
+ buffer.resize(encoder.GetBufferSize());
fidoUri = "FIDO:/" + DigitEncode(buffer);
}
THROW_ENCODING("cbor_encode_text_stringz() failed with " << static_cast<int>(err));
}
-void Container::AppendTextString(const std::string_view &text)
+void Container::AppendTextString(const std::string_view &value)
{
assert(!m_appendingToChild);
CborError err;
- err = cbor_encode_text_string(&m_encoder, text.data(), text.size());
+ err = cbor_encode_text_string(&m_encoder, value.data(), value.size());
if (err != CborNoError)
THROW_ENCODING("cbor_encode_text_string() failed with " << static_cast<int>(err));
}
AppendByteString(value);
}
+void SortedMap::AppendTextStringAt(const Key &key, const std::string_view &value)
+{
+ AddKey(key);
+ AppendTextString(value);
+}
+
void SortedMap::AppendTextStringZAt(const Key &key, const char *value)
{
assert(value);