* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
- *
- *
- * @file serialization.cpp
- * @version 1.0
- * @brief This file is the implementation file of data serialization
*/
-#include <stddef.h>
+#include <cstring>
+#include <iostream>
+
#include <serialization.h>
+#include <message-buffer.h>
+
+
+namespace WA {
+
+// For array item
+void __serializeArrayItem(IStream& stream, const void *data, size_t struct_size) {
+ MessageBuffer& buffer = dynamic_cast<MessageBuffer&>(stream);
+ buffer.Write(struct_size, data);
+}
+void __deserializeArrayItem(IStream& stream, void **data, size_t struct_size) {
+ MessageBuffer& buffer = dynamic_cast<MessageBuffer&>(stream);
+ *data = buffer.Ptr();
+ char buf[struct_size];
+ buffer.Read(struct_size, buf); // for moving internal offset.
+}
+
+// For struct body itself
+void WAuthnCtypeSerializer::serializeStructBody(IStream& stream, const void *data, size_t struct_size) {
+ size_t lengh = (data == nullptr) ? 0 : struct_size;
+ serialize(stream, reinterpret_cast<const unsigned char*>(data), lengh);
+}
+void WAuthnCtypeSerializer::deserializeStructBody(IStream& stream, void **data, size_t struct_size) {
+ size_t length = 0;
+ deserialize(stream, reinterpret_cast<unsigned char**>(data), &length);
+ if (length != 0 && length != struct_size)
+ ThrowMsg(SerializationException::InvalidStreamData, "Invalid length: length=" << length
+ << ", struct_size=" << struct_size);
+}
+
+// For unsigned char*
+void WAuthnCtypeSerializer::serialize(IStream& stream, const unsigned char* data, size_t length) {
+ stream.Write(sizeof(size_t), &length);
+ if (length > MAX_BUFFER_SIZE)
+ ThrowMsg(SerializationException::InvalidStreamData, "Too large length of data to write: length=" << length);
+ if (length != 0)
+ stream.Write(length, data);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, unsigned char** data, size_t* length) {
+ MessageBuffer& buffer = dynamic_cast<MessageBuffer&>(stream);
+ buffer.Read(sizeof(size_t), length);
+ if (*length > MAX_BUFFER_SIZE)
+ ThrowMsg(SerializationException::InvalidStreamData, "Too large length of data to read: length=" << *length);
+ if (*length == 0) {
+ *data = nullptr;
+ } else {
+ *data = buffer.Ptr();
+ char buf[*length];
+ buffer.Read(*length, buf); // for moving internal offset.
+ }
+}
+
+// For char*
+void WAuthnCtypeSerializer::serialize(IStream& stream, const char* data) {
+ size_t length = (data) ? strlen(data) + 1 : 0;
+ serialize(stream, reinterpret_cast<const unsigned char*>(data), length);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, char** data) {
+ size_t length;
+ deserialize(stream, reinterpret_cast<unsigned char**>(data), &length);
+ if (*data != nullptr && length != strlen(*data) + 1)
+ ThrowMsg(SerializationException::InvalidStreamData,
+ "Invalid length of cstring (not expected one): "
+ << " length=" << length <<", strlen(string)+1=" << strlen(*data) + 1);
+}
+
+// For wauthn_error_e
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_error_e data) {
+ // Serialization::Serialize(stream, static_cast<int>(data));
+ stream.Write(sizeof(data), &data);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_error_e* data) {
+ int tmp = 0;
+ stream.Read(sizeof(tmp), &tmp);
+ *data = static_cast<wauthn_error_e>(tmp);
+}
+
+// For wauthn_buffer_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_buffer_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_buffer_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->data, data->size);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_buffer_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_buffer_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->data), &((*data)->size));
+}
+
+// For wauthn_authenticator_attestation_response_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_authenticator_attestation_response_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_authenticator_attestation_response_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->client_data_json);
+ serialize(stream, data->attestation_object);
+ serialize(stream, data->authenticator_data);
+ serialize(stream, data->subject_pubkey_info);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_authenticator_attestation_response_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_authenticator_attestation_response_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->client_data_json));
+ deserialize(stream, &((*data)->attestation_object));
+ deserialize(stream, &((*data)->authenticator_data));
+ deserialize(stream, &((*data)->subject_pubkey_info));
+}
+
+// For wauthn_authenticator_assertion_response_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_authenticator_assertion_response_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_authenticator_assertion_response_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->client_data_json);
+ serialize(stream, data->authenticator_data);
+ serialize(stream, data->signature);
+ serialize(stream, data->user_handle);
+ serialize(stream, data->attestation_object);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_authenticator_assertion_response_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_authenticator_assertion_response_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->client_data_json));
+ deserialize(stream, &((*data)->authenticator_data));
+ deserialize(stream, &((*data)->signature));
+ deserialize(stream, &((*data)->user_handle));
+ deserialize(stream, &((*data)->attestation_object));
+}
+
+// For wauthn_rp_entity_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_rp_entity_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_rp_entity_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->name);
+ serialize(stream, data->id);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_rp_entity_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_rp_entity_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->name));
+ deserialize(stream, &((*data)->id));
+}
+
+// For wauthn_user_entity_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_user_entity_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_user_entity_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->name);
+ serialize(stream, data->id);
+ serialize(stream, data->display_name);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_user_entity_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_user_entity_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->name));
+ deserialize(stream, &((*data)->id));
+ deserialize(stream, &((*data)->display_name));
+}
+
+// For wauthn_pubkey_cred_param_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_pubkey_cred_param_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_pubkey_cred_param_s));
+ // No pointers in struct
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_cred_param_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_pubkey_cred_param_s));
+ // No pointers in struct
+}
+
+// For wauthn_pubkey_cred_params_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_pubkey_cred_params_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_pubkey_cred_params_s));
+ if (data == nullptr)
+ return;
+ // Serialize array
+ for(size_t i=0; i < data->size; i++ )
+ __serializeArrayItem(stream, reinterpret_cast<const void *>(data->params + i), sizeof(wauthn_pubkey_cred_params_s));
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_cred_params_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_pubkey_cred_params_s));
+ if (*data == nullptr)
+ return;
+ if ((*data)->size == 0) {
+ (*data)->params = nullptr;
+ }
+ // Deseriallize array
+ wauthn_pubkey_cred_param_s* tmp;
+ for(size_t i=0; i < (*data)->size; i++ ) {
+ __deserializeArrayItem(stream, reinterpret_cast<void **>(&tmp), sizeof(wauthn_pubkey_cred_params_s));
+ if (i == 0) // set pointer to the first parameter
+ (*data)->params = tmp;
+ }
+}
+
+// For wauthn_pubkey_cred_descriptor_s
+void __serializePointerContents(IStream& stream, const wauthn_pubkey_cred_descriptor_s* data) {
+ WAuthnCtypeSerializer::serialize(stream, data->id);
+}
+void __deserializePointerContents(IStream& stream, wauthn_pubkey_cred_descriptor_s* data) {
+ WAuthnCtypeSerializer::deserialize(stream, &(data->id));
+}
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_pubkey_cred_descriptor_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_pubkey_cred_descriptor_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ __serializePointerContents(stream, data);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_cred_descriptor_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_pubkey_cred_descriptor_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ __deserializePointerContents(stream, *data);
+}
+
+// For wauthn_pubkey_cred_descriptors_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_pubkey_cred_descriptors_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_pubkey_cred_descriptors_s));
+ if (data == nullptr)
+ return;
+ // Serialize array
+ for(size_t i=0; i < data->size; i++ )
+ __serializeArrayItem(stream, reinterpret_cast<const void *>(data->descriptors + i), sizeof(wauthn_pubkey_cred_descriptor_s));
+ // Seriallize the contents of pointers in struct array
+ for(size_t i=0; i < data->size; i++ )
+ __serializePointerContents(stream, data->descriptors + i);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_cred_descriptors_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_pubkey_cred_descriptors_s));
+ if (*data == nullptr)
+ return;
+ if ((*data)->size == 0) {
+ (*data)->descriptors = nullptr;
+ return;
+ }
+ // Deseriallize array
+ wauthn_pubkey_cred_descriptor_s* tmp;
+ for(size_t i=0; i < (*data)->size; i++ ) {
+ __deserializeArrayItem(stream, reinterpret_cast<void **>(&tmp), sizeof(wauthn_pubkey_cred_descriptor_s));
+ if (i == 0) // set pointer to the first parameter
+ (*data)->descriptors = tmp;
+ }
+ // Deseriallize the contents of pointers in struct array
+ for(size_t i=0; i < (*data)->size; i++ )
+ __deserializePointerContents(stream, (*data)->descriptors + i);
+}
+
+// For wauthn_authentication_ext_s
+void __serializePointerContents(IStream& stream, const wauthn_authentication_ext_s* data) {
+ WAuthnCtypeSerializer::serialize(stream, data->extension_id);
+ WAuthnCtypeSerializer::serialize(stream, data->extension_value);
+}
+void __deserializePointerContents(IStream& stream, wauthn_authentication_ext_s* data) {
+ WAuthnCtypeSerializer::deserialize(stream, &(data->extension_id));
+ WAuthnCtypeSerializer::deserialize(stream, &(data->extension_value));
+}
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_authentication_ext_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_authentication_ext_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ __serializePointerContents(stream, data);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_authentication_ext_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_authentication_ext_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ __deserializePointerContents(stream, *data);
+}
+
+// For wauthn_authentication_exts_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_authentication_exts_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_authentication_exts_s));
+ if (data == nullptr)
+ return;
+ // Serialize array
+ for(size_t i=0; i < data->size; i++ )
+ __serializeArrayItem(stream, reinterpret_cast<const void *>(data->extensions + i), sizeof(wauthn_authentication_ext_s));
+ // Seriallize the contents of pointers in struct array
+ for(size_t i=0; i < data->size; i++ )
+ __serializePointerContents(stream, data->extensions + i);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_authentication_exts_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_authentication_exts_s));
+ if (*data == nullptr)
+ return;
+ if ((*data)->size == 0) {
+ (*data)->extensions = nullptr;
+ return;
+ }
+ // Deseriallize array
+ wauthn_authentication_ext_s* tmp;
+ for(size_t i=0; i < (*data)->size; i++ ) {
+ __deserializeArrayItem(stream, reinterpret_cast<void **>(&tmp), sizeof(wauthn_authentication_ext_s));
+ if (i == 0) // set pointer to the first parameter
+ (*data)->extensions = tmp;
+ }
+ // Deseriallize the contents of pointers in struct array
+ for(size_t i=0; i < (*data)->size; i++ )
+ __deserializePointerContents(stream, (*data)->extensions + i);
+}
+
+// For wauthn_authenticator_sel_cri_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_authenticator_sel_cri_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_authenticator_sel_cri_s));
+ // No pointers in struct
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_authenticator_sel_cri_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_authenticator_sel_cri_s));
+ // No pointers in struct
+}
+
+// For wauthn_pubkey_cred_hints_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_pubkey_cred_hints_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_pubkey_cred_hints_s));
+ if (data == nullptr)
+ return;
+ // Serialize array
+ for(size_t i=0; i < data->size; i++ )
+ __serializeArrayItem(stream, reinterpret_cast<const void *>(data->hints + i), sizeof(wauthn_pubkey_cred_hint_e));
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_cred_hints_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_pubkey_cred_hints_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize array
+ wauthn_pubkey_cred_hint_e* tmp;
+ for(size_t i=0; i < (*data)->size; i++ ) {
+ __deserializeArrayItem(stream, reinterpret_cast<void **>(&tmp), sizeof(wauthn_pubkey_cred_hint_e));
+ if (i == 0) // set pointer to the first parameter
+ (*data)->hints = tmp;
+ }
+}
+
+// For wauthn_hybrid_linked_data_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_hybrid_linked_data_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_hybrid_linked_data_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->contact_id);
+ serialize(stream, data->link_id);
+ serialize(stream, data->link_secret);
+ serialize(stream, data->authenticator_pubkey);
+ serialize(stream, data->authenticator_name);
+ serialize(stream, data->signature);
+ serialize(stream, data->auth_pubkey);
+ serialize(stream, data->tunnel_server_domain);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_hybrid_linked_data_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_hybrid_linked_data_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->contact_id));
+ deserialize(stream, &((*data)->link_id));
+ deserialize(stream, &((*data)->link_secret));
+ deserialize(stream, &((*data)->authenticator_pubkey));
+ deserialize(stream, &((*data)->authenticator_name));
+ deserialize(stream, &((*data)->signature));
+ deserialize(stream, &((*data)->auth_pubkey));
+ deserialize(stream, &((*data)->tunnel_server_domain));
+}
+
+// For wauthn_attestation_formats_s
+void __serializePointerContents(IStream& stream, const wauthn_buffer_s* data) {
+ WAuthnCtypeSerializer::serialize(stream, data);
+}
+void __deserializePointerContents(IStream& stream, wauthn_buffer_s* data) {
+ WAuthnCtypeSerializer::deserialize(stream, &data);
+}
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_attestation_formats_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_attestation_formats_s));
+ if (data == nullptr)
+ return;
+ // Serialize array
+ for(size_t i=0; i < data->size; i++ )
+ __serializeArrayItem(stream, reinterpret_cast<const void *>(data->attestation_formats + i), sizeof(wauthn_buffer_s));
+ // Seriallize the contents of pointers in struct array
+ for(size_t i=0; i < data->size; i++ )
+ __serializePointerContents(stream, data->attestation_formats + i);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_attestation_formats_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_attestation_formats_s));
+ if (*data == nullptr)
+ return;
+ if ((*data)->size == 0) {
+ (*data)->attestation_formats = nullptr;
+ return;
+ }
+ // Deseriallize array
+ wauthn_buffer_s* tmp;
+ for(size_t i=0; i < (*data)->size; i++ ) {
+ __deserializeArrayItem(stream, reinterpret_cast<void **>(&tmp), sizeof(wauthn_buffer_s));
+ if (i == 0) // set pointer to the first parameter
+ (*data)->attestation_formats = tmp;
+ }
+ // Deseriallize the contents of pointers in struct array
+ for(size_t i=0; i < (*data)->size; i++ )
+ __deserializePointerContents(stream, (*data)->attestation_formats + i);
+}
+
+// For wauthn_pubkey_cred_creation_options_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_pubkey_cred_creation_options_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_pubkey_cred_creation_options_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->rp);
+ serialize(stream, data->user);
+ serialize(stream, data->challenge);
+ serialize(stream, data->pubkey_cred_params);
+ serialize(stream, data->exclude_credentials);
+ serialize(stream, data->authenticator_selection);
+ serialize(stream, data->hints);
+ serialize(stream, data->attestation_formats);
+ serialize(stream, data->extensions);
+ serialize(stream, data->linked_device);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_cred_creation_options_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_pubkey_cred_creation_options_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->rp));
+ deserialize(stream, &((*data)->user));
+ deserialize(stream, &((*data)->challenge));
+ deserialize(stream, &((*data)->pubkey_cred_params));
+ deserialize(stream, &((*data)->exclude_credentials));
+ deserialize(stream, &((*data)->authenticator_selection));
+ deserialize(stream, &((*data)->hints));
+ deserialize(stream, &((*data)->attestation_formats));
+ deserialize(stream, &((*data)->extensions));
+ deserialize(stream, &((*data)->linked_device));
+}
+
+// For wauthn_pubkey_cred_request_options_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_pubkey_cred_request_options_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_pubkey_cred_request_options_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->challenge);
+ serialize(stream, data->rpId);
+ serialize(stream, data->allow_credentials);
+ serialize(stream, data->hints);
+ serialize(stream, data->attestation_formats);
+ serialize(stream, data->extensions);
+ serialize(stream, data->linked_device);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_cred_request_options_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_pubkey_cred_request_options_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->challenge));
+ deserialize(stream, &((*data)->rpId));
+ deserialize(stream, &((*data)->allow_credentials));
+ deserialize(stream, &((*data)->hints));
+ deserialize(stream, &((*data)->attestation_formats));
+ deserialize(stream, &((*data)->extensions));
+ deserialize(stream, &((*data)->linked_device));
+}
+
+// For wauthn_pubkey_credential_attestaion_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_pubkey_credential_attestaion_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_pubkey_credential_attestaion_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->id);
+ serialize(stream, data->rawId);
+ serialize(stream, data->response);
+ serialize(stream, data->extensions);
+ serialize(stream, data->json_data);
+ serialize(stream, data->linked_device);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_credential_attestaion_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_pubkey_credential_attestaion_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->id));
+ deserialize(stream, &((*data)->rawId));
+ deserialize(stream, &((*data)->response));
+ deserialize(stream, &((*data)->extensions));
+ deserialize(stream, &((*data)->json_data));
+ deserialize(stream, &((*data)->linked_device));
+}
+
+// For wauthn_pubkey_credential_assertion_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_pubkey_credential_assertion_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_pubkey_credential_assertion_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->id);
+ serialize(stream, data->rawId);
+ serialize(stream, data->response);
+ serialize(stream, data->extensions);
+ serialize(stream, data->json_data);
+ serialize(stream, data->linked_device);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_credential_assertion_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_pubkey_credential_assertion_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->id));
+ deserialize(stream, &((*data)->rawId));
+ deserialize(stream, &((*data)->response));
+ deserialize(stream, &((*data)->extensions));
+ deserialize(stream, &((*data)->json_data));
+ deserialize(stream, &((*data)->linked_device));
+}
+
+// For wauthn_client_data_s
+void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_client_data_s* data) {
+ // Seriallize struct itself
+ serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_client_data_s));
+ if (data == nullptr)
+ return;
+ // Seriallize the contents of struct's pointers
+ serialize(stream, data->client_data_json);
+}
+void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_client_data_s** data) {
+ // Deseriallize struct itself
+ deserializeStructBody(stream, reinterpret_cast<void **>(data), sizeof(wauthn_client_data_s));
+ if (*data == nullptr)
+ return;
+ // Deseriallize the contents of struct's pointers
+ deserialize(stream, &((*data)->client_data_json));
+}
+
-//
-// Note:
-//
-// The file here is left blank to enable precompilation
-// of templates in corresponding header file.
-// Do not remove this file.
-//
+} // namespace WebAuthn
#include <tuple>
#include <exception.h>
+#include <webauthn-types.h>
namespace WA {
const Collection &get() { return col_; }
};
+
+const size_t MAX_BUFFER_SIZE = 128 * 1024 * 1024; // 128 MB
+
+// Serialize & Deserialze struct types in wetauthn-types.h
+struct WAuthnCtypeSerializer {
+private:
+ static void serializeStructBody(IStream& stream, const void *data, size_t struct_size);
+ static void deserializeStructBody(IStream& stream, void **data, size_t struct_size);
+
+public:
+ static void serialize(IStream& stream, const unsigned char* data, size_t length);
+ static void deserialize(IStream& stream, unsigned char** data, size_t* length);
+
+ static void serialize(IStream& stream, const char* data);
+ static void deserialize(IStream& stream, char** data);
+
+ static void serialize(IStream& stream, const wauthn_error_e data);
+ static void deserialize(IStream& stream, wauthn_error_e* data);
+
+ static void serialize(IStream& stream, const wauthn_buffer_s* data);
+ static void deserialize(IStream& stream, wauthn_buffer_s** data);
+
+ static void serialize(IStream& stream, const wauthn_authenticator_attestation_response_s* data);
+ static void deserialize(IStream& stream, wauthn_authenticator_attestation_response_s** data);
+
+ static void serialize(IStream& stream, const wauthn_authenticator_assertion_response_s* data);
+ static void deserialize(IStream& stream, wauthn_authenticator_assertion_response_s** data);
+
+ static void serialize(IStream& stream, const wauthn_rp_entity_s* data);
+ static void deserialize(IStream& stream, wauthn_rp_entity_s** data);
+
+ static void serialize(IStream& stream, const wauthn_user_entity_s* data);
+ static void deserialize(IStream& stream, wauthn_user_entity_s** data);
+
+ static void serialize(IStream& stream, const wauthn_pubkey_cred_param_s* data);
+ static void deserialize(IStream& stream, wauthn_pubkey_cred_param_s** data);
+
+ static void serialize(IStream& stream, const wauthn_pubkey_cred_params_s* data);
+ static void deserialize(IStream& stream, wauthn_pubkey_cred_params_s** data);
+
+ static void serialize(IStream& stream, const wauthn_pubkey_cred_descriptor_s* data);
+ static void deserialize(IStream& stream, wauthn_pubkey_cred_descriptor_s** data);
+
+ static void serialize(IStream& stream, const wauthn_pubkey_cred_descriptors_s* data);
+ static void deserialize(IStream& stream, wauthn_pubkey_cred_descriptors_s** data);
+
+ static void serialize(IStream& stream, const wauthn_authentication_ext_s* data);
+ static void deserialize(IStream& stream, wauthn_authentication_ext_s** data);
+
+ static void serialize(IStream& stream, const wauthn_authentication_exts_s* data);
+ static void deserialize(IStream& stream, wauthn_authentication_exts_s** data);
+
+ static void serialize(IStream& stream, const wauthn_authenticator_sel_cri_s* data);
+ static void deserialize(IStream& stream, wauthn_authenticator_sel_cri_s** data);
+
+ static void serialize(IStream& stream, const wauthn_pubkey_cred_hints_s* data);
+ static void deserialize(IStream& stream, wauthn_pubkey_cred_hints_s** data);
+
+ static void serialize(IStream& stream, const wauthn_hybrid_linked_data_s* data);
+ static void deserialize(IStream& stream, wauthn_hybrid_linked_data_s** data);
+
+ static void serialize(IStream& stream, const wauthn_attestation_formats_s* data);
+ static void deserialize(IStream& stream, wauthn_attestation_formats_s** data);
+
+ static void serialize(IStream& stream, const wauthn_pubkey_cred_creation_options_s* data);
+ static void deserialize(IStream& stream, wauthn_pubkey_cred_creation_options_s** data);
+
+ static void serialize(IStream& stream, const wauthn_pubkey_cred_request_options_s* data);
+ static void deserialize(IStream& stream, wauthn_pubkey_cred_request_options_s** data);
+
+ static void serialize(IStream& stream, const wauthn_pubkey_credential_attestaion_s* data);
+ static void deserialize(IStream& stream, wauthn_pubkey_credential_attestaion_s** data);
+
+ static void serialize(IStream& stream, const wauthn_pubkey_credential_assertion_s* data);
+ static void deserialize(IStream& stream, wauthn_pubkey_credential_assertion_s** data);
+
+ static void serialize(IStream& stream, const wauthn_client_data_s* data);
+ static void deserialize(IStream& stream, wauthn_client_data_s** data);
+};
+
struct Serialization {
// serialization
// normal functions
{
stream.Write(sizeof(value), &value);
}
- static void Serialize(IStream& stream, const char* const value)
- {
- stream.Write(sizeof(*value), value);
- }
+ // The following function conflicts with Serialize function for WAuthn C Types.
+ // static void Serialize(IStream& stream, const char* const value)
+ // {
+ // stream.Write(sizeof(*value), value);
+ // }
// unsigned char
static void Serialize(IStream& stream, const unsigned char value)
Serialize(stream, first);
Serialize(stream, second, tail...);
}
+
+ // For WAuthn C Types
+
+ // For char*
+ static void Serialize(IStream& stream, const char* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_error_e
+ static void Serialize(IStream& stream, const wauthn_error_e data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_buffer_s
+ static void Serialize(IStream& stream, const wauthn_buffer_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_authenticator_attestation_response_s
+ static void Serialize(IStream& stream, const wauthn_authenticator_attestation_response_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_authenticator_assertion_response_s
+ static void Serialize(IStream& stream, const wauthn_authenticator_assertion_response_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_rp_entity_s
+ static void Serialize(IStream& stream, const wauthn_rp_entity_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_user_entity_s
+ static void Serialize(IStream& stream, const wauthn_user_entity_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_pubkey_cred_param_s
+ static void Serialize(IStream& stream, const wauthn_pubkey_cred_param_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_pubkey_cred_params_s
+ static void Serialize(IStream& stream, const wauthn_pubkey_cred_params_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_pubkey_cred_descriptor_s
+ static void Serialize(IStream& stream, const wauthn_pubkey_cred_descriptor_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_pubkey_cred_descriptors_s
+ static void Serialize(IStream& stream, const wauthn_pubkey_cred_descriptors_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_authentication_ext_s
+ static void Serialize(IStream& stream, const wauthn_authentication_ext_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_authentication_exts_s
+ static void Serialize(IStream& stream, const wauthn_authentication_exts_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_rp_entity_s
+ static void Serialize(IStream& stream, const wauthn_authenticator_sel_cri_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_pubkey_cred_hints_s
+ static void Serialize(IStream& stream, const wauthn_pubkey_cred_hints_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_hybrid_linked_data_s
+ static void Serialize(IStream& stream, const wauthn_hybrid_linked_data_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_attestation_formats_s
+ static void Serialize(IStream& stream, const wauthn_attestation_formats_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_pubkey_cred_creation_options_s
+ static void Serialize(IStream& stream, const wauthn_pubkey_cred_creation_options_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_pubkey_cred_request_options_s
+ static void Serialize(IStream& stream, const wauthn_pubkey_cred_request_options_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_pubkey_credential_attestaion_s
+ static void Serialize(IStream& stream, const wauthn_pubkey_credential_attestaion_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_pubkey_credential_assertion_s
+ static void Serialize(IStream& stream, const wauthn_pubkey_credential_assertion_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+ // For wauthn_client_data_s
+ static void Serialize(IStream& stream, const wauthn_client_data_s* data)
+ {
+ WAuthnCtypeSerializer::serialize(stream, data);
+ }
+
}; // struct Serialization
struct Deserialization {
}
template<typename T1, typename T2, typename... Tail>
- static void Deserialize(IStream& stream, T1 &first, T2 &second, Tail&... tail)
+ static void Deserialize(IStream& stream, T1 &&first, T2 &&second, Tail&&... tail)
{
Deserialization::Deserialize(stream, first);
Deserialization::Deserialize(stream, second, tail...);
}
+
+ // For WAuthn C Types
+
+ // For wauthn_error_e
+ static void Deserialize(IStream& stream, wauthn_error_e* data)
+ {
+ WAuthnCtypeSerializer::deserialize(stream, data);
+ }
+
+ //##########################################################################################
+ // WARNING
+ // 1. The stream must be an instance of MessageBuffer.
+ // 2. The returned data(more exactly *data) points to somewhere of m_buffer of MessageBuffer.
+ // So the returned data is only valid while the stream is alive.
+ //###########################################################################################
+ // This convers all other C types.
+ template<typename T>
+ static void Deserialize(IStream& stream, T** data)
+ {
+ WAuthnCtypeSerializer::deserialize(stream, data);
+ }
+
}; // struct Deserialization
+
+
} // namespace WebAuthn
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ *
+ * @file webauthn-client-test.cpp
+ * @version 1.0
+ * @brief unit tests for webauthn client api
+ */
+
+
+#include <string>
+#include <cstring>
+#include <iostream>
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include <webauthn-types.h>
+#include <message-buffer.h>
+#include <serialization.h>
+
+
+namespace WA {
+
+
+namespace CommonTestData {
+ unsigned char clientDataJsonRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char attestationObjectRaw[16] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char authenticatorDataRaw[26] = {0x21, 0x22, 0x23, 0x24, };
+ unsigned char subjectPubkeyInfoRaw[36] = {0x31, 0x32, 0x33, 0x34, };
+ wauthn_buffer_s clientDataJson = {clientDataJsonRaw, sizeof(clientDataJsonRaw)};
+ wauthn_buffer_s attestationObject = {attestationObjectRaw, sizeof(attestationObjectRaw)};
+ unsigned int transports = 3;
+ wauthn_buffer_s authenticatorData = {authenticatorDataRaw, sizeof(authenticatorDataRaw)};
+ wauthn_buffer_s subjectPubkeyInfo = {subjectPubkeyInfoRaw, sizeof(subjectPubkeyInfoRaw)};
+ wauthn_cose_algorithm_e pubkey_alg = WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256;
+ wauthn_authenticator_attestation_response_s authenticatorAttestationResponse
+ = {&clientDataJson, &attestationObject, transports, &authenticatorData, &subjectPubkeyInfo, pubkey_alg};
+ wauthn_authenticator_attestation_response_s emptyAuthenticatorAttestationResponse
+ = {nullptr, nullptr, 0x00, nullptr, nullptr, pubkey_alg};
+
+ unsigned char signatureRaw[26] = {0x21, 0x22, 0x23, 0x24, };
+ unsigned char userHnadleRaw[36] = {0x31, 0x32, 0x33, 0x34, };
+ wauthn_buffer_s signature = {signatureRaw, sizeof(signatureRaw)};
+ wauthn_buffer_s userHnadle = {userHnadleRaw, sizeof(userHnadleRaw)};
+ wauthn_authenticator_assertion_response_s authenticatorAssertionResponse
+ = {&clientDataJson, &authenticatorData, &signature, &userHnadle, &attestationObject};
+ wauthn_authenticator_assertion_response_s emptyAuthenticatorAssertionResponse
+ = {nullptr, nullptr, nullptr, nullptr, nullptr};
+
+ const char *name = "test name";
+ const char *id = "test id";
+ wauthn_rp_entity_s rpEntity = {const_cast<char*>(name), const_cast<char*>(id)};
+ wauthn_rp_entity_s emptyRpEntiy = {nullptr, nullptr};
+
+ unsigned char idRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+ wauthn_buffer_s bufferId = {idRaw, sizeof(idRaw)};
+ const char *displayName = "test displayName";
+ wauthn_user_entity_s userEntity = {const_cast<char*>(name), &bufferId, const_cast<char*>(displayName)};
+ wauthn_user_entity_s emptyUserEntity = {nullptr, nullptr, nullptr};
+
+ wauthn_pubkey_cred_type_e pubkeyCredType = pct_public_key;
+ wauthn_pubkey_cred_param_s credParam0 = {pubkeyCredType, WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256};
+ wauthn_pubkey_cred_param_s credParam1 = {pubkeyCredType, WAUTHN_COSE_ALGORITHM_ECDSA_P521_WITH_SHA512};
+ wauthn_pubkey_cred_param_s pubkeyCredParam2[2] = {credParam0, credParam1};
+ wauthn_pubkey_cred_params_s pubkeyCredParams2 = {sizeof(pubkeyCredParam2)/sizeof(pubkeyCredParam2[0]), pubkeyCredParam2};
+ wauthn_pubkey_cred_param_s pubkeyCredParam1[1] = {credParam0};
+ wauthn_pubkey_cred_params_s pubkeyCredParams1 = {sizeof(pubkeyCredParam1)/sizeof(pubkeyCredParam1[0]), pubkeyCredParam1};
+ wauthn_pubkey_cred_params_s emptyPubkeyCredParams = {0, nullptr};
+
+ wauthn_pubkey_cred_descriptor_s pubkeyCredDescriptor = {pubkeyCredType, &bufferId, 3};
+ wauthn_pubkey_cred_descriptor_s emptyPubkeyCredDescriptor = {pubkeyCredType, nullptr, 0};
+
+ unsigned char idRaw0[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char idRaw1[16] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_buffer_s bufferId0 = {idRaw0, sizeof(idRaw0)};
+ wauthn_buffer_s bufferId1 = {idRaw1, sizeof(idRaw1)};
+ wauthn_pubkey_cred_descriptor_s credDescriptor0 = {pubkeyCredType, &bufferId0, 3};
+ wauthn_pubkey_cred_descriptor_s credDescriptor1 = {pubkeyCredType, &bufferId1, 13};
+ wauthn_pubkey_cred_descriptor_s pubkeyCredDescriptor2[2] = {credDescriptor0, credDescriptor1};
+ wauthn_pubkey_cred_descriptors_s pubkeyCredDescriptors2 = {sizeof(pubkeyCredDescriptor2)/sizeof(pubkeyCredDescriptor2[0]),
+ pubkeyCredDescriptor2};
+ wauthn_pubkey_cred_descriptor_s pubkeyCredDescriptor1[1] = {credDescriptor0};
+ wauthn_pubkey_cred_descriptors_s pubkeyCredDescriptors1 = {sizeof(pubkeyCredDescriptor1)/sizeof(pubkeyCredDescriptor1[0]),
+ pubkeyCredDescriptor1};
+ wauthn_pubkey_cred_descriptors_s emptyPubkeyCredDescriptors = {0, nullptr};
+
+ unsigned char extensionIdRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char extensionValueRaw[16] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_buffer_s extensionId = {extensionIdRaw, sizeof(extensionIdRaw)};
+ wauthn_buffer_s extensionValue = {extensionValueRaw, sizeof(extensionValueRaw)};
+ wauthn_authentication_ext_s authenticationExt = {&extensionId, &extensionValue};
+ wauthn_authentication_ext_s emptyAuthenticationExt = {nullptr, nullptr};
+
+ unsigned char extensionIdRaw1[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char extensionValueRaw1[16] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_buffer_s extensionId1 = {extensionIdRaw1, sizeof(extensionIdRaw1)};
+ wauthn_buffer_s extensionValue1 = {extensionValueRaw1, sizeof(extensionValueRaw1)};
+ wauthn_authentication_ext_s authenticationExt1 = {&extensionId1, &extensionValue1};
+ wauthn_authentication_ext_s authenticationExtArr1[1] = {authenticationExt};
+ wauthn_authentication_ext_s authenticationExtArr2[2] = {authenticationExt, authenticationExt1};
+ wauthn_authentication_exts_s authenticationExts1 = {sizeof(authenticationExtArr1)/sizeof(authenticationExtArr1[0]),
+ authenticationExtArr1};
+ wauthn_authentication_exts_s authenticationExts2 = {sizeof(authenticationExtArr2)/sizeof(authenticationExtArr2[0]),
+ authenticationExtArr2};
+ wauthn_authentication_exts_s emptyAuthenticationExts = {0, nullptr};
+
+ wauthn_authenticator_attachment_e attachment = aa_platform;
+ wauthn_resident_key_requirement_e resident_key = rkr_preferred;
+ bool require_resident_key = false;
+ wauthn_user_verification_requirement_e user_verification = uvr_discouraged;
+ wauthn_authenticator_sel_cri_s authenticatorSelCri = {attachment, resident_key,
+ require_resident_key, user_verification};
+
+ wauthn_pubkey_cred_hint_e hint0 = pch_security_key;
+ wauthn_pubkey_cred_hint_e hint1 = pch_client_device;
+ wauthn_pubkey_cred_hint_e hintAarr1[1] = {hint0};
+ wauthn_pubkey_cred_hint_e hintAarr2[2] = {hint0, hint1};
+ wauthn_pubkey_cred_hints_s pubkeyCredHints1 = {sizeof(hintAarr1)/sizeof(hintAarr1[0]), hintAarr1};
+ wauthn_pubkey_cred_hints_s pubkeyCredHints2 = {sizeof(hintAarr2)/sizeof(hintAarr2[0]), hintAarr2};
+ wauthn_pubkey_cred_hints_s emptyPubkeyCredHints = {0, nullptr};
+
+ unsigned char contactIdRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char linkIdRaw[16] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char linkSecretRaw[26] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char authenticatorPubkeyRaw[16] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char authenticatorNameRaw[26] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char authPubkeyRaw[36] = {0x11, 0x12, 0x13, 0x14, };
+ unsigned char tunnelServerDomainRaw[36] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_buffer_s contactId = {contactIdRaw, sizeof(contactIdRaw)};
+ wauthn_buffer_s linkId = {linkIdRaw, sizeof(linkIdRaw)};
+ wauthn_buffer_s linkSecret = {linkSecretRaw, sizeof(linkSecretRaw)};
+ wauthn_buffer_s authenticatorPubkey = {authenticatorPubkeyRaw, sizeof(authenticatorPubkeyRaw)};
+ wauthn_buffer_s authenticatorName = {authenticatorNameRaw, sizeof(authenticatorNameRaw)};
+ wauthn_buffer_s authPubkey = {authPubkeyRaw, sizeof(authPubkeyRaw)};
+ wauthn_buffer_s tunnelServerDomain = {tunnelServerDomainRaw, sizeof(tunnelServerDomainRaw)};
+ wauthn_hybrid_linked_data_s hybirdLinkedData = {&contactId, &linkId, &linkSecret, &authenticatorPubkey,
+ &authenticatorName, &signature, &authPubkey, &tunnelServerDomain};
+ wauthn_hybrid_linked_data_s emptyHybirdLinkedData = {nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr};
+
+ unsigned char bufferRaw0[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned char bufferRaw1[16] = {0x11, 0x12, 0x13, 0x14, };
+ wauthn_buffer_s buffer0 = {bufferRaw0, sizeof(bufferRaw0)};
+ wauthn_buffer_s buffer1 = {bufferRaw1, sizeof(bufferRaw1)};
+ wauthn_buffer_s bufferArr1[1] = {buffer0};
+ wauthn_buffer_s bufferArr2[2] = {buffer0, buffer1};
+ wauthn_attestation_formats_s attestationFormats1 = {sizeof(bufferArr1)/sizeof(bufferArr1[0]), bufferArr1};
+ wauthn_attestation_formats_s attestationFormats2 = {sizeof(bufferArr2)/sizeof(bufferArr2[0]), bufferArr2};
+ wauthn_attestation_formats_s emptyAttestationFormats = {0, nullptr};
+
+ unsigned char challengeRaw[06] = {0x01, 0x02, 0x03, 0x04, };
+ unsigned long timeout = 1000;
+ wauthn_buffer_s challenge = {challengeRaw, sizeof(challengeRaw)};
+ wauthn_attestation_pref_e attestation = ap_direct;
+ wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptions = {&rpEntity, &userEntity, &challenge,
+ &pubkeyCredParams2, timeout, &pubkeyCredDescriptors2, &authenticatorSelCri, &pubkeyCredHints2,
+ attestation, &attestationFormats1, &authenticationExts2, &hybirdLinkedData};
+ wauthn_pubkey_cred_creation_options_s emptyPubkeyCredCreationOptions = {nullptr, nullptr, nullptr,
+ nullptr, 0, nullptr, nullptr, nullptr, ap_none, nullptr, nullptr, nullptr};
+
+ const char *rpId = "test RP ID";
+ wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptions = {&challenge, timeout, const_cast<char *>(rpId),
+ &pubkeyCredDescriptors2, user_verification, &pubkeyCredHints2, attestation, &attestationFormats1,
+ &authenticationExts2, &hybirdLinkedData};
+ wauthn_pubkey_cred_request_options_s emptyPubkeyCredRequestOptions = {nullptr, 0, nullptr,
+ nullptr, uvr_none, nullptr, ap_none, nullptr, nullptr, nullptr};
+
+ bool is_conditional_mediation_available = false;
+ wauthn_pubkey_credential_attestaion_s pubkeyCredentialAttestation = {&bufferId, pubkeyCredType, &bufferId0,
+ &authenticatorAttestationResponse, attachment, &authenticationExts2, is_conditional_mediation_available,
+ &buffer1, &hybirdLinkedData};
+ wauthn_pubkey_credential_attestaion_s emptyPubkeyCredentialAttestation = {nullptr, pubkeyCredType, nullptr,
+ nullptr, attachment, nullptr, is_conditional_mediation_available, nullptr, nullptr};
+
+ wauthn_pubkey_credential_assertion_s pubkeyCredentialAssertion = {&bufferId, pubkeyCredType, &bufferId0,
+ &authenticatorAssertionResponse, attachment, &authenticationExts2, is_conditional_mediation_available,
+ &buffer1, &hybirdLinkedData};
+ wauthn_pubkey_credential_assertion_s emptyPubkeyCredentialAssertion = {nullptr, pubkeyCredType, nullptr,
+ nullptr, attachment, nullptr, is_conditional_mediation_available, nullptr, nullptr};
+
+ wauthn_hash_algorithm_e hashAlg = WAUTHN_HASH_ALGORITHM_SHA_256;
+ wauthn_client_data_s clientData = {&bufferId, hashAlg};
+ wauthn_client_data_s emptyClientData = {nullptr, hashAlg};
+}
+
+class WAuthnSerializationTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ int ret = WAUTHN_ERROR_NONE;
+ // Do initialization if needed.
+ if (ret != WAUTHN_ERROR_NONE) {
+ std::cout << "[webauthn_initialize] failed." << std::endl;
+ return;
+ }
+ }
+
+ void TearDown() override {
+ int ret = WAUTHN_ERROR_NONE;
+ // Do deinitialization if needed.
+ if (ret != WAUTHN_ERROR_NONE) {
+ std::cout << "[webauthn_deinitialize] failed." << std::endl;
+ return;
+ }
+ }
+};
+
+template<typename T, typename U>
+void __serializeDeserializeWtihWAuthnCtypeSerializer(MessageBuffer& buffer, T data, U deserialized)
+{
+ buffer.InitForStreaming();
+ WAuthnCtypeSerializer::serialize(buffer, data);
+ buffer.ModeOutput();
+
+ buffer.ModeStreaming();
+ WAuthnCtypeSerializer::deserialize(buffer, deserialized);
+}
+
+template<typename T, typename U>
+void __serializeDeserializeStruct(MessageBuffer& buffer, T data, U deserialized)
+{
+ buffer.InitForStreaming();
+ Serialization::Serialize(buffer, data);
+ buffer.ModeOutput();
+
+ buffer.ModeStreaming();
+ Deserialization::Deserialize(buffer, deserialized);
+}
+
+template<typename T, typename F>
+void __testSerialization(T data, F cmpfunction)
+{
+ MessageBuffer buffer0;
+ T deserialized0;
+ __serializeDeserializeWtihWAuthnCtypeSerializer(buffer0, data, &deserialized0);
+ EXPECT_EQ(cmpfunction(data, deserialized0), true);
+
+ MessageBuffer buffer1;
+ T deserialized1;
+ __serializeDeserializeStruct(buffer1, data, &deserialized1);
+ EXPECT_EQ(cmpfunction(data, deserialized1), true);
+}
+
+bool __compareWAuthnBuffers(const wauthn_buffer_s *expected, const wauthn_buffer_s *actual)
+{
+ if (expected == nullptr || actual == nullptr) {
+ return (expected == actual);
+ } else {
+ if (expected->size != actual->size)
+ return false;
+ if (memcmp(expected->data, actual->data, expected->size) != 0)
+ return false;
+ return true;
+ }
+}
+
+bool __compareCstring(const char *expected, const char *actual)
+{
+ if (expected == nullptr || actual == nullptr) {
+ return (expected == actual);
+ } else {
+ return (strcmp(expected, actual) == 0);
+ }
+}
+
+void __testUnsignedCharPtr(unsigned char *data, size_t data_size)
+{
+ MessageBuffer buffer;
+ unsigned char *deserialized = nullptr;
+ size_t deserialized_len = 0;
+
+ buffer.InitForStreaming();
+ WAuthnCtypeSerializer::serialize(buffer, data, data_size);
+ buffer.ModeOutput();
+
+ buffer.ModeStreaming();
+ WAuthnCtypeSerializer::deserialize(buffer, &deserialized, &deserialized_len);
+
+ EXPECT_EQ(data_size, deserialized_len);
+ EXPECT_EQ(memcmp(data, deserialized, deserialized_len), 0);
+ if (deserialized == nullptr || deserialized_len == 0) {
+ EXPECT_EQ(deserialized, nullptr);
+ EXPECT_EQ(deserialized_len, 0);
+ }
+ if (data == nullptr) {
+ EXPECT_EQ(deserialized, nullptr);
+ }
+}
+TEST_F(WAuthnSerializationTest, unsignedCharPtr)
+{
+ unsigned char data[13] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,};
+ unsigned char *nulldata = nullptr;
+
+ __testUnsignedCharPtr(data, sizeof(data));
+ __testUnsignedCharPtr(nulldata, 0);
+}
+
+TEST_F(WAuthnSerializationTest, CharPtr)
+{
+ char *data = const_cast<char *>("This is a test data.");
+ char *size0data = const_cast<char *>("");
+ char *nulldata = nullptr;
+
+ __testSerialization(data, __compareCstring);
+ __testSerialization(size0data, __compareCstring);
+ __testSerialization(nulldata, __compareCstring);
+}
+
+
+bool __compareWAuthErrorE(wauthn_error_e expected, wauthn_error_e actual)
+{
+ return (expected == actual);
+}
+TEST_F(WAuthnSerializationTest, wauthn_error_e)
+{
+ __testSerialization(WAUTHN_ERROR_NONE, __compareWAuthErrorE);
+ __testSerialization(WAUTHN_ERROR_NOT_ALLOWED, __compareWAuthErrorE);
+ __testSerialization(WAUTHN_ERROR_ENCODING_FAILED, __compareWAuthErrorE);
+ __testSerialization(WAUTHN_ERROR_CANCELLED, __compareWAuthErrorE);
+}
+
+TEST_F(WAuthnSerializationTest, wauthn_buffer_s)
+{
+ unsigned char testdata[26] = {0x01, 0x02, 0x03, 0x04, };
+ wauthn_buffer_s buffer = {testdata, sizeof(testdata)};
+ __testSerialization(&buffer, __compareWAuthnBuffers);
+
+ wauthn_buffer_s emptyBuffer = {nullptr, 0x00};
+ __testSerialization(&emptyBuffer, __compareWAuthnBuffers);
+
+ __testSerialization(static_cast<wauthn_buffer_s *>(nullptr), __compareWAuthnBuffers);
+}
+
+bool __compareWAuthnAuthenticatorAttestationResponseS(
+ const wauthn_authenticator_attestation_response_s *expected,
+ const wauthn_authenticator_attestation_response_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (__compareWAuthnBuffers(expected->client_data_json, actual->client_data_json) == false)
+ return false;
+ if (__compareWAuthnBuffers(expected->attestation_object, actual->attestation_object) == false)
+ return false;
+ if (expected->transports != actual->transports)
+ return false;
+ if (__compareWAuthnBuffers(expected->authenticator_data, actual->authenticator_data) == false)
+ return false;
+ if (__compareWAuthnBuffers(expected->subject_pubkey_info, actual->subject_pubkey_info) == false)
+ return false;
+ if (expected->pubkey_alg != actual->pubkey_alg)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_authenticator_attestation_response_s)
+{
+ __testSerialization(&CommonTestData::authenticatorAttestationResponse,
+ __compareWAuthnAuthenticatorAttestationResponseS);
+ __testSerialization(&CommonTestData::emptyAuthenticatorAttestationResponse,
+ __compareWAuthnAuthenticatorAttestationResponseS);
+ __testSerialization(static_cast<wauthn_authenticator_attestation_response_s *>(nullptr),
+ __compareWAuthnAuthenticatorAttestationResponseS);
+
+}
+
+bool __compareWAuthnAuthenticatorAssertionResponseS(
+ const wauthn_authenticator_assertion_response_s *expected,
+ const wauthn_authenticator_assertion_response_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (__compareWAuthnBuffers(expected->client_data_json, actual->client_data_json) == false)
+ return false;
+ if (__compareWAuthnBuffers(expected->attestation_object, actual->attestation_object) == false)
+ return false;
+ if (__compareWAuthnBuffers(expected->signature, actual->signature) == false)
+ return false;
+ if (__compareWAuthnBuffers(expected->user_handle, actual->user_handle) == false)
+ return false;
+ if (__compareWAuthnBuffers(expected->attestation_object, actual->attestation_object) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_authenticator_assertion_response_s)
+{
+ __testSerialization(&CommonTestData::authenticatorAssertionResponse,
+ __compareWAuthnAuthenticatorAssertionResponseS);
+ __testSerialization(&CommonTestData::emptyAuthenticatorAssertionResponse,
+ __compareWAuthnAuthenticatorAssertionResponseS);
+ __testSerialization(static_cast<wauthn_authenticator_assertion_response_s *>(nullptr),
+ __compareWAuthnAuthenticatorAssertionResponseS);
+}
+
+bool __compareWAuthnRpEntityS(const wauthn_rp_entity_s *expected,
+ const wauthn_rp_entity_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (__compareCstring(expected->name, actual->name) == false)
+ return false;
+ if (__compareCstring(expected->id, actual->id) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_rp_entity_s)
+{
+ __testSerialization(&CommonTestData::rpEntity, __compareWAuthnRpEntityS);
+ __testSerialization(&CommonTestData::emptyRpEntiy, __compareWAuthnRpEntityS);
+ __testSerialization(static_cast<wauthn_rp_entity_s *>(nullptr), __compareWAuthnRpEntityS);
+}
+
+bool __compareWAuthnUserEntityS(const wauthn_user_entity_s *expected,
+ const wauthn_user_entity_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (__compareCstring(expected->name, actual->name) == false)
+ return false;
+ if (__compareWAuthnBuffers(expected->id, actual->id) == false)
+ return false;
+ if (__compareCstring(expected->display_name, actual->display_name) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_user_entity_s)
+{
+ __testSerialization(&CommonTestData::userEntity, __compareWAuthnUserEntityS);
+ __testSerialization(&CommonTestData::emptyUserEntity, __compareWAuthnUserEntityS);
+ __testSerialization(static_cast<wauthn_user_entity_s *>(nullptr), __compareWAuthnUserEntityS);
+}
+
+
+bool __compareWAuthnPubkeyCredParamS(const wauthn_pubkey_cred_param_s *expected,
+ const wauthn_pubkey_cred_param_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (actual->type != expected->type)
+ return false;
+ if (actual->alg != expected->alg)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_pubkey_cred_param_s)
+{
+ wauthn_pubkey_cred_param_s data1 = {pct_public_key, WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256};
+ wauthn_pubkey_cred_param_s data2 = {pct_public_key, WAUTHN_COSE_ALGORITHM_ECDSA_P521_WITH_SHA512};
+
+ __testSerialization(&data1, __compareWAuthnPubkeyCredParamS);
+ __testSerialization(&data2, __compareWAuthnPubkeyCredParamS);
+ __testSerialization(static_cast<wauthn_pubkey_cred_param_s *>(nullptr), __compareWAuthnPubkeyCredParamS);
+}
+
+bool __compareWAuthnPubkeyCredParamsS(const wauthn_pubkey_cred_params_s *expected,
+ const wauthn_pubkey_cred_params_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (actual->size != expected->size)
+ return false;
+ for (size_t i=0; i < expected->size; i++)
+ if(__compareWAuthnPubkeyCredParamS(expected->params + i, expected->params + i) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_pubkey_cred_params_s)
+{
+ __testSerialization(&CommonTestData::pubkeyCredParams2, __compareWAuthnPubkeyCredParamsS);
+ __testSerialization(&CommonTestData::pubkeyCredParams1, __compareWAuthnPubkeyCredParamsS);
+ __testSerialization(&CommonTestData::emptyPubkeyCredParams, __compareWAuthnPubkeyCredParamsS);
+ __testSerialization(static_cast<wauthn_pubkey_cred_params_s *>(nullptr), __compareWAuthnPubkeyCredParamsS);
+}
+
+
+bool __compareWAuthnPubkeyCredDescriptorS(const wauthn_pubkey_cred_descriptor_s *expected,
+ const wauthn_pubkey_cred_descriptor_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (actual->type != expected->type)
+ return false;
+ if (__compareWAuthnBuffers(actual->id, expected->id) == false)
+ return false;
+ if (actual->transports != expected->transports)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_pubkey_cred_descriptor_s)
+{
+ __testSerialization(&CommonTestData::pubkeyCredDescriptor, __compareWAuthnPubkeyCredDescriptorS);
+ __testSerialization(&CommonTestData::emptyPubkeyCredDescriptor, __compareWAuthnPubkeyCredDescriptorS);
+ __testSerialization(static_cast<wauthn_pubkey_cred_descriptor_s *>(nullptr), __compareWAuthnPubkeyCredDescriptorS);
+}
+
+bool __compareWAuthnPubkeyCredDescriptorsS(const wauthn_pubkey_cred_descriptors_s *expected,
+ const wauthn_pubkey_cred_descriptors_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (actual->size != expected->size)
+ return false;
+ for (size_t i=0; i < expected->size; i++)
+ if(__compareWAuthnPubkeyCredDescriptorS(expected->descriptors + i, expected->descriptors + i) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_pubkey_cred_descriptors_s)
+{
+ __testSerialization(&CommonTestData::pubkeyCredDescriptors2, __compareWAuthnPubkeyCredDescriptorsS);
+ __testSerialization(&CommonTestData::pubkeyCredDescriptors1, __compareWAuthnPubkeyCredDescriptorsS);
+ __testSerialization(&CommonTestData::emptyPubkeyCredDescriptors, __compareWAuthnPubkeyCredDescriptorsS);
+ __testSerialization(static_cast<wauthn_pubkey_cred_descriptors_s *>(nullptr), __compareWAuthnPubkeyCredDescriptorsS);
+}
+
+
+bool __compareWAuthnAuthenticationExtS(const wauthn_authentication_ext_s *expected,
+ const wauthn_authentication_ext_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (__compareWAuthnBuffers(actual->extension_id, expected->extension_id) == false)
+ return false;
+ if (__compareWAuthnBuffers(actual->extension_value, expected->extension_value) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_authentication_ext_s)
+{
+ __testSerialization(&CommonTestData::authenticationExt, __compareWAuthnAuthenticationExtS);
+ __testSerialization(&CommonTestData::emptyAuthenticationExt, __compareWAuthnAuthenticationExtS);
+ __testSerialization(static_cast<wauthn_authentication_ext_s *>(nullptr), __compareWAuthnAuthenticationExtS);
+}
+
+bool __compareWAuthnAuthenticationExtsS(const wauthn_authentication_exts_s *expected,
+ const wauthn_authentication_exts_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (actual->size != expected->size)
+ return false;
+ for (size_t i=0; i < expected->size; i++)
+ if(__compareWAuthnAuthenticationExtS(expected->extensions + i, expected->extensions + i) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_authentication_exts_s)
+{
+ __testSerialization(&CommonTestData::authenticationExts1, __compareWAuthnAuthenticationExtsS);
+ __testSerialization(&CommonTestData::authenticationExts2, __compareWAuthnAuthenticationExtsS);
+ __testSerialization(&CommonTestData::emptyAuthenticationExts, __compareWAuthnAuthenticationExtsS);
+ __testSerialization(static_cast<wauthn_authentication_exts_s *>(nullptr), __compareWAuthnAuthenticationExtsS);
+}
+
+bool __compareWAuthnAuthenticatorSelCriS(const wauthn_authenticator_sel_cri_s *expected,
+ const wauthn_authenticator_sel_cri_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (actual->attachment != expected->attachment)
+ return false;
+ if (actual->resident_key != expected->resident_key)
+ return false;
+ if (actual->require_resident_key != expected->require_resident_key)
+ return false;
+ if (actual->user_verification != expected->user_verification)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_authenticator_sel_cri_s)
+{
+ __testSerialization(&CommonTestData::authenticatorSelCri, __compareWAuthnAuthenticatorSelCriS);
+ __testSerialization(static_cast<wauthn_authenticator_sel_cri_s *>(nullptr), __compareWAuthnAuthenticatorSelCriS);
+}
+
+
+bool __compareWAuthnPubkeyCredHintE(const wauthn_pubkey_cred_hint_e *expected,
+ const wauthn_pubkey_cred_hint_e *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (*actual != *expected)
+ return false;
+ return true;
+}
+bool __compareWAuthnPubkeyCredHintsE(const wauthn_pubkey_cred_hints_s *expected,
+ const wauthn_pubkey_cred_hints_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (actual->size != expected->size)
+ return false;
+ for (size_t i=0; i < expected->size; i++)
+ if(__compareWAuthnPubkeyCredHintE(expected->hints + i, expected->hints + i) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_pubkey_cred_hints_s)
+{
+ __testSerialization(&CommonTestData::pubkeyCredHints1, __compareWAuthnPubkeyCredHintsE);
+ __testSerialization(&CommonTestData::pubkeyCredHints2, __compareWAuthnPubkeyCredHintsE);
+ __testSerialization(&CommonTestData::emptyPubkeyCredHints, __compareWAuthnPubkeyCredHintsE);
+ __testSerialization(static_cast<wauthn_pubkey_cred_hints_s *>(nullptr), __compareWAuthnPubkeyCredHintsE);
+}
+
+bool __compareWAuthnHybridLinkedDataS(const wauthn_hybrid_linked_data_s *expected,
+ const wauthn_hybrid_linked_data_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (__compareWAuthnBuffers(actual->contact_id, expected->contact_id) == false)
+ return false;
+ if (__compareWAuthnBuffers(actual->link_id, expected->link_id) == false)
+ return false;
+ if (__compareWAuthnBuffers(actual->link_secret, expected->link_secret) == false)
+ return false;
+ if (__compareWAuthnBuffers(actual->authenticator_pubkey, expected->authenticator_pubkey) == false)
+ return false;
+ if (__compareWAuthnBuffers(actual->authenticator_name, expected->authenticator_name) == false)
+ return false;
+ if (__compareWAuthnBuffers(actual->signature, expected->signature) == false)
+ return false;
+ if (__compareWAuthnBuffers(actual->auth_pubkey, expected->auth_pubkey) == false)
+ return false;
+ if (__compareWAuthnBuffers(actual->tunnel_server_domain, expected->tunnel_server_domain) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_hybrid_linked_data_s)
+{
+ __testSerialization(&CommonTestData::hybirdLinkedData, __compareWAuthnHybridLinkedDataS);
+ __testSerialization(&CommonTestData::emptyHybirdLinkedData, __compareWAuthnHybridLinkedDataS);
+ __testSerialization(static_cast<wauthn_hybrid_linked_data_s *>(nullptr), __compareWAuthnHybridLinkedDataS);
+}
+
+bool __compareWAuthnAttestationFormatsS(const wauthn_attestation_formats_s *expected,
+ const wauthn_attestation_formats_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if (actual->size != expected->size)
+ return false;
+ for (size_t i=0; i < expected->size; i++)
+ if(__compareWAuthnBuffers(expected->attestation_formats + i,
+ actual->attestation_formats + i) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_attestation_formats_s)
+{
+ __testSerialization(&CommonTestData::attestationFormats1, __compareWAuthnAttestationFormatsS);
+ __testSerialization(&CommonTestData::attestationFormats2, __compareWAuthnAttestationFormatsS);
+ __testSerialization(&CommonTestData::emptyAttestationFormats, __compareWAuthnAttestationFormatsS);
+ __testSerialization(static_cast<wauthn_attestation_formats_s *>(nullptr), __compareWAuthnAttestationFormatsS);
+}
+
+bool __compareWAuthnPubkeyCredCreationOptionsS(const wauthn_pubkey_cred_creation_options_s *expected,
+ const wauthn_pubkey_cred_creation_options_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if(__compareWAuthnRpEntityS(expected->rp, actual->rp) == false)
+ return false;
+ if(__compareWAuthnUserEntityS(expected->user, actual->user) == false)
+ return false;
+ if(__compareWAuthnBuffers(expected->challenge, actual->challenge) == false)
+ return false;
+ if(__compareWAuthnPubkeyCredParamsS(expected->pubkey_cred_params, actual->pubkey_cred_params) == false)
+ return false;
+ if (expected->timeout != actual->timeout)
+ return false;
+ if(__compareWAuthnPubkeyCredDescriptorsS(expected->exclude_credentials, actual->exclude_credentials) == false)
+ return false;
+ if(__compareWAuthnAuthenticatorSelCriS(expected->authenticator_selection, actual->authenticator_selection) == false)
+ return false;
+ if(__compareWAuthnPubkeyCredHintsE(expected->hints, actual->hints) == false)
+ return false;
+ if (expected->attestation != actual->attestation)
+ return false;
+ if(__compareWAuthnAttestationFormatsS(expected->attestation_formats, actual->attestation_formats) == false)
+ return false;
+ if(__compareWAuthnAuthenticationExtsS(expected->extensions, actual->extensions) == false)
+ return false;
+ if(__compareWAuthnHybridLinkedDataS(expected->linked_device, actual->linked_device) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_pubkey_cred_creation_options_s)
+{
+ __testSerialization(&CommonTestData::pubkeyCredCreationOptions,
+ __compareWAuthnPubkeyCredCreationOptionsS);
+ __testSerialization(&CommonTestData::emptyPubkeyCredCreationOptions,
+ __compareWAuthnPubkeyCredCreationOptionsS);
+ __testSerialization(static_cast<wauthn_pubkey_cred_creation_options_s *>(nullptr),
+ __compareWAuthnPubkeyCredCreationOptionsS);
+}
+
+
+bool __compareWAuthnPubkeyCredRequestOptionsS(const wauthn_pubkey_cred_request_options_s *expected,
+ const wauthn_pubkey_cred_request_options_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if(__compareWAuthnBuffers(expected->challenge, actual->challenge) == false)
+ return false;
+ if (expected->timeout != actual->timeout)
+ return false;
+ if(__compareCstring(expected->rpId, actual->rpId) == false)
+ return false;
+ if(__compareWAuthnPubkeyCredDescriptorsS(expected->allow_credentials, actual->allow_credentials) == false)
+ return false;
+ if (expected->user_verification != actual->user_verification)
+ return false;
+ if(__compareWAuthnPubkeyCredHintsE(expected->hints, actual->hints) == false)
+ return false;
+ if (expected->attestation != actual->attestation)
+ return false;
+ if(__compareWAuthnAttestationFormatsS(expected->attestation_formats, actual->attestation_formats) == false)
+ return false;
+ if(__compareWAuthnAuthenticationExtsS(expected->extensions, actual->extensions) == false)
+ return false;
+ if(__compareWAuthnHybridLinkedDataS(expected->linked_device, actual->linked_device) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_pubkey_cred_request_options_s)
+{
+ __testSerialization(&CommonTestData::pubkeyCredRequestOptions,
+ __compareWAuthnPubkeyCredRequestOptionsS);
+ __testSerialization(&CommonTestData::emptyPubkeyCredRequestOptions,
+ __compareWAuthnPubkeyCredRequestOptionsS);
+ __testSerialization(static_cast<wauthn_pubkey_cred_request_options_s *>(nullptr),
+ __compareWAuthnPubkeyCredRequestOptionsS);
+}
+
+
+bool __compareWAuthnPubkeyCredentialAttestionS(const wauthn_pubkey_credential_attestaion_s *expected,
+ const wauthn_pubkey_credential_attestaion_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if(__compareWAuthnBuffers(expected->id, actual->id) == false)
+ return false;
+ if (expected->type != actual->type)
+ return false;
+ if(__compareWAuthnAuthenticatorAttestationResponseS(expected->response, actual->response) == false)
+ return false;
+ if(__compareWAuthnBuffers(expected->rawId, actual->rawId) == false)
+ return false;
+ if (expected->authenticator_attachment != actual->authenticator_attachment)
+ return false;
+ if(__compareWAuthnAuthenticationExtsS(expected->extensions, actual->extensions) == false)
+ return false;
+ if (expected->is_conditional_mediation_available != actual->is_conditional_mediation_available)
+ return false;
+ if(__compareWAuthnBuffers(expected->json_data, actual->json_data) == false)
+ return false;
+ if(__compareWAuthnHybridLinkedDataS(expected->linked_device, actual->linked_device) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_pubkey_credential_attestaion_s)
+{
+ __testSerialization(&CommonTestData::pubkeyCredentialAttestation,
+ __compareWAuthnPubkeyCredentialAttestionS);
+ __testSerialization(&CommonTestData::emptyPubkeyCredentialAttestation,
+ __compareWAuthnPubkeyCredentialAttestionS);
+ __testSerialization(static_cast<wauthn_pubkey_credential_attestaion_s *>(nullptr),
+ __compareWAuthnPubkeyCredentialAttestionS);
+}
+
+
+bool __compareWAuthnPubkeyCredentialAssertionS(const wauthn_pubkey_credential_assertion_s *expected,
+ const wauthn_pubkey_credential_assertion_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if(__compareWAuthnBuffers(expected->id, actual->id) == false)
+ return false;
+ if (expected->type != actual->type)
+ return false;
+ if(__compareWAuthnAuthenticatorAssertionResponseS(expected->response, actual->response) == false)
+ return false;
+ if(__compareWAuthnBuffers(expected->rawId, actual->rawId) == false)
+ return false;
+ if (expected->authenticator_attachment != actual->authenticator_attachment)
+ return false;
+ if(__compareWAuthnAuthenticationExtsS(expected->extensions, actual->extensions) == false)
+ return false;
+ if (expected->is_conditional_mediation_available != actual->is_conditional_mediation_available)
+ return false;
+ if(__compareWAuthnBuffers(expected->json_data, actual->json_data) == false)
+ return false;
+ if(__compareWAuthnHybridLinkedDataS(expected->linked_device, actual->linked_device) == false)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_pubkey_credential_assertion_s)
+{
+ __testSerialization(&CommonTestData::pubkeyCredentialAssertion,
+ __compareWAuthnPubkeyCredentialAssertionS);
+ __testSerialization(&CommonTestData::emptyPubkeyCredentialAssertion,
+ __compareWAuthnPubkeyCredentialAssertionS);
+ __testSerialization(static_cast<wauthn_pubkey_credential_assertion_s *>(nullptr),
+ __compareWAuthnPubkeyCredentialAssertionS);
+}
+
+
+bool __compareWAuthnClientDataS(const wauthn_client_data_s *expected, const wauthn_client_data_s *actual)
+{
+ if (actual == nullptr || expected == nullptr)
+ return (actual == expected);
+ if(__compareWAuthnBuffers(expected->client_data_json, actual->client_data_json) == false)
+ return false;
+ if (expected->hash_alg != actual->hash_alg)
+ return false;
+ return true;
+}
+TEST_F(WAuthnSerializationTest, wauthn_client_data_s)
+{
+ __testSerialization(&CommonTestData::clientData, __compareWAuthnClientDataS);
+ __testSerialization(&CommonTestData::emptyClientData, __compareWAuthnClientDataS);
+ __testSerialization(static_cast<wauthn_client_data_s *>(nullptr), __compareWAuthnClientDataS);
+}
+
+template<typename T, typename U, typename FT, typename FU>
+void __testMultipleSerialization(T first, U second, FT cmpfirst, FU cmpsecond)
+{
+ T deserialized_first;
+ U deserialized_second;
+
+ MessageBuffer buffer;
+ buffer.InitForStreaming();
+ Serialization::Serialize(buffer, first, second);
+ buffer.ModeOutput();
+
+ buffer.ModeStreaming();
+ Deserialization::Deserialize(buffer, &deserialized_first, &deserialized_second);
+
+ EXPECT_EQ(cmpfirst(first, deserialized_first), true);
+ EXPECT_EQ(cmpsecond(second, deserialized_second), true);
+}
+
+TEST_F(WAuthnSerializationTest, multiple_serialization_mcreq)
+{
+ wauthn_client_data_s *client_data = &CommonTestData::clientData;
+ wauthn_pubkey_cred_creation_options_s *options = &CommonTestData::pubkeyCredCreationOptions;
+
+ __testMultipleSerialization(client_data, options,
+ __compareWAuthnClientDataS, __compareWAuthnPubkeyCredCreationOptionsS);
+}
+
+TEST_F(WAuthnSerializationTest, multiple_serialization_gareq)
+{
+ wauthn_client_data_s *client_data = &CommonTestData::clientData;
+ wauthn_pubkey_cred_request_options_s *options = &CommonTestData::pubkeyCredRequestOptions;
+
+ __testMultipleSerialization(client_data, options,
+ __compareWAuthnClientDataS, __compareWAuthnPubkeyCredRequestOptionsS);
+}
+
+TEST_F(WAuthnSerializationTest, multiple_serialization_mcres)
+{
+ wauthn_pubkey_credential_attestaion_s *pubkeyCred = &CommonTestData::pubkeyCredentialAttestation;
+ wauthn_error_e result = WAUTHN_ERROR_PERMISSION_DENIED;
+
+ __testMultipleSerialization(pubkeyCred, result,
+ __compareWAuthnPubkeyCredentialAttestionS, __compareWAuthErrorE);
+}
+
+TEST_F(WAuthnSerializationTest, multiple_serialization_gares)
+{
+ wauthn_pubkey_credential_assertion_s *pubkeyCred = &CommonTestData::pubkeyCredentialAssertion;
+ wauthn_error_e result = WAUTHN_ERROR_CANCELLED;
+
+ __testMultipleSerialization(pubkeyCred, result,
+ __compareWAuthnPubkeyCredentialAssertionS, __compareWAuthErrorE);
+}
+
+
+} // namespace WA
\ No newline at end of file