namespace WA {
+// For alignment
+constexpr size_t __getAlignSize() {
+ return sizeof(size_t);
+}
+
+size_t __getPaddingSize(size_t data_size) {
+ constexpr size_t alignSize = __getAlignSize();
+ return (alignSize - (data_size % alignSize)) % alignSize;
+}
+
+void __addAlignmentPadding(IStream& stream, size_t data_size) {
+ size_t paddingSize = __getPaddingSize(data_size);
+ if (paddingSize > 0) {
+ size_t padding = 0;
+ stream.Write(paddingSize, &padding);
+ }
+}
+
+void __removeAlignmentPadding(IStream& stream, size_t data_size) {
+ size_t paddingSize = __getPaddingSize(data_size);
+ if (paddingSize > 0) {
+ size_t padding = 0;
+ stream.Read(paddingSize, &padding);
+ }
+}
+
+void __checkAlignment(const char *name, const void *ptr) {
+ constexpr size_t alignSize = __getAlignSize();
+ size_t pointer = reinterpret_cast<size_t>(ptr);
+ if ( (ptr != nullptr) && (pointer % alignSize != 0) ) {
+ ThrowMsg(SerializationException::InvalidStreamData,
+ "Invalid Alignment of Pointer: pointer addr=" << pointer
+ << ", name=" << name << std::endl);
+ }
+}
+
// For array item
void __serializeArrayItem(IStream& stream, const void *data, size_t struct_size) {
stream.Write(struct_size, data);
"Too big array size: size=" << size);
}
+void __serializeArray(IStream& stream, size_t array_cnt, const unsigned char *data, size_t struct_size) {
+ for(size_t i=0; i < array_cnt; i++)
+ __serializeArrayItem(stream, data + (i * struct_size), struct_size);
+ __addAlignmentPadding(stream, array_cnt * struct_size);
+}
+
+void __deserializeArray(IStream& stream, size_t array_cnt, unsigned char **data, size_t struct_size) {
+ unsigned char *tmp = nullptr;
+ for(size_t i=0; i < array_cnt; i++) {
+ __deserializeArrayItem(stream, reinterpret_cast<void **>(&tmp), struct_size);
+ if (i == 0) // set pointer to the first parameter
+ *data = tmp;
+ }
+ __removeAlignmentPadding(stream, array_cnt * struct_size);
+}
+
// For struct body itself
void WAuthnCtypeSerializer::serializeStructBody(IStream& stream, const void *data, size_t struct_size) {
size_t length = (data == nullptr) ? 0 : struct_size;
serialize(stream, reinterpret_cast<const unsigned char*>(data), length);
+ __addAlignmentPadding(stream, struct_size);
}
void WAuthnCtypeSerializer::deserializeStructBody(IStream& stream, void **data, size_t struct_size) {
if (data == nullptr)
if (length != 0 && length != struct_size)
ThrowMsg(SerializationException::InvalidStreamData, "Invalid length: length=" << length
<< ", struct_size=" << struct_size);
+ __removeAlignmentPadding(stream, struct_size);
}
// For unsigned char*
stream.Write(sizeof(size_t), &length);
if (length != 0)
stream.Write(length, data);
+ __addAlignmentPadding(stream, length);
}
void WAuthnCtypeSerializer::deserialize(IStream& stream, const unsigned char** data, size_t* length) {
if (data == nullptr || length == nullptr)
// for moving internal offset.
char buf[*length];
buffer.Read(*length, buf);
+ __removeAlignmentPadding(stream, *length);
}
// For char*
}
void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_error_e data) {
__checkValidity(data);
- // Serialization::Serialize(stream, static_cast<int>(data));
- stream.Write(sizeof(data), &data);
+ int tmp = static_cast<int>(data);
+ stream.Write(sizeof(tmp), &tmp);
}
void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_error_e* data) {
if (data == nullptr)
return;
// Deserialize the contents of struct's pointers
deserialize(stream, &((*data)->data), &((*data)->size));
+ __checkAlignment("wauthn_const_buffer_s->data", (*data)->data);
}
// For wauthn_authenticator_attestation_response_s
+void __checkAlignment(const wauthn_authenticator_attestation_response_s* data) {
+ if (data == nullptr)
+ return;
+ __checkAlignment("wauthn_authenticator_attestation_response_s->client_data_json", data->client_data_json);
+ __checkAlignment("wauthn_authenticator_attestation_response_s->attestation_object", data->attestation_object);
+ __checkAlignment("wauthn_authenticator_attestation_response_s->authenticator_data", data->authenticator_data);
+ __checkAlignment("wauthn_authenticator_attestation_response_s->subject_pubkey_info", data->subject_pubkey_info);
+}
void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_authenticator_attestation_response_s* data) {
// Serialize struct itself
serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_authenticator_attestation_response_s));
deserialize(stream, &((*data)->attestation_object));
deserialize(stream, &((*data)->authenticator_data));
deserialize(stream, &((*data)->subject_pubkey_info));
+
+ __checkAlignment(*data);
}
// For wauthn_authenticator_assertion_response_s
+void __checkAlignment(const wauthn_authenticator_assertion_response_s* data) {
+ if (data == nullptr)
+ return;
+ __checkAlignment("wauthn_authenticator_assertion_response_s->client_data_json", data->client_data_json);
+ __checkAlignment("wauthn_authenticator_assertion_response_s->authenticator_data", data->authenticator_data);
+ __checkAlignment("wauthn_authenticator_assertion_response_s->signature", data->signature);
+ __checkAlignment("wauthn_authenticator_assertion_response_s->user_handle", data->user_handle);
+ __checkAlignment("wauthn_authenticator_assertion_response_s->attestation_object", data->attestation_object);
+}
void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_authenticator_assertion_response_s* data) {
// Serialize struct itself
serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_authenticator_assertion_response_s));
deserialize(stream, &((*data)->signature));
deserialize(stream, &((*data)->user_handle));
deserialize(stream, &((*data)->attestation_object));
+
+ __checkAlignment(*data);
}
// For wauthn_rp_entity_s
+void __checkAlignment(const wauthn_rp_entity_s* data) {
+ if (data == nullptr)
+ return;
+ __checkAlignment("wauthn_rp_entity_s->name", data->name);
+ __checkAlignment("wauthn_rp_entity_s->id", data->id);
+}
void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_rp_entity_s* data) {
// Serialize struct itself
serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_rp_entity_s));
// Deserialize the contents of struct's pointers
deserialize(stream, &((*data)->name));
deserialize(stream, &((*data)->id));
+
+ __checkAlignment(*data);
}
// For wauthn_user_entity_s
+void __checkAlignment(const wauthn_user_entity_s* data) {
+ if (data == nullptr)
+ return;
+ __checkAlignment("wauthn_user_entity_s->name", data->name);
+ __checkAlignment("wauthn_user_entity_s->id", data->id);
+ __checkAlignment("wauthn_user_entity_s->display_name", data->display_name);
+}
void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_user_entity_s* data) {
// Serialize struct itself
serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_user_entity_s));
deserialize(stream, &((*data)->name));
deserialize(stream, &((*data)->id));
deserialize(stream, &((*data)->display_name));
+
+ __checkAlignment(*data);
}
// For wauthn_pubkey_cred_param_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));
+ __serializeArray(stream, data->size, reinterpret_cast<const unsigned char *>(data->params),
+ sizeof(wauthn_pubkey_cred_params_s));
}
void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_cred_params_s** data) {
// Deserialize struct itself
}
__checkValidity(*data);
// Deserialize 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;
- }
+ __deserializeArray(stream, (*data)->size, reinterpret_cast<unsigned char **>(&((*data)->params)),
+ sizeof(wauthn_pubkey_cred_params_s));
+ __checkAlignment("wauthn_pubkey_cred_params_s->params", (*data)->params);
}
// For wauthn_pubkey_cred_descriptor_s
__checkValidity(*data);
// Deserialize the contents of struct's pointers
__deserializePointerContents(stream, *data);
+ __checkAlignment("wauthn_pubkey_cred_descriptor_s->id", (*data)->id);
}
// For 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));
+ __serializeArray(stream, data->size, reinterpret_cast<const unsigned char *>(data->descriptors),
+ sizeof(wauthn_pubkey_cred_descriptor_s));
// Serialize the contents of pointers in struct array
for(size_t i=0; i < data->size; i++ )
__serializePointerContents(stream, data->descriptors + i);
return;
}
// Deserialize 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;
- }
+ __deserializeArray(stream, (*data)->size, reinterpret_cast<unsigned char **>(&((*data)->descriptors)),
+ sizeof(wauthn_pubkey_cred_descriptor_s));
// Deserialize the contents of pointers in struct array
for(size_t i=0; i < (*data)->size; i++ )
__deserializePointerContents(stream, (*data)->descriptors + i);
+ __checkAlignment("wauthn_pubkey_cred_descriptors_s->descriptors", (*data)->descriptors);
}
// For wauthn_authentication_ext_s
+void __checkAlignment(const wauthn_authentication_ext_s* data) {
+ __checkAlignment("wauthn_authentication_ext_s->extension_id", data->extension_id);
+ __checkAlignment("wauthn_authentication_ext_s->extension_value", data->extension_value);
+}
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) {
// Serialize struct itself
return;
// Deserialize the contents of struct's pointers
__deserializePointerContents(stream, *data);
+
+ __checkAlignment(*data);
}
// For 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));
+ __serializeArray(stream, data->size, reinterpret_cast<const unsigned char *>(data->extensions),
+ sizeof(wauthn_authentication_ext_s));
// Serialize the contents of pointers in struct array
for(size_t i=0; i < data->size; i++ )
__serializePointerContents(stream, data->extensions + i);
return;
}
// Deserialize 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;
- }
+ __deserializeArray(stream, (*data)->size, reinterpret_cast<unsigned char **>(&((*data)->extensions)),
+ sizeof(wauthn_authentication_ext_s));
// Deserialize the contents of pointers in struct array
for(size_t i=0; i < (*data)->size; i++ )
__deserializePointerContents(stream, (*data)->extensions + i);
+
+ __checkAlignment("wauthn_authentication_exts_s->extensions", (*data)->extensions);
}
// For wauthn_authenticator_sel_cri_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));
+ __serializeArray(stream, data->size, reinterpret_cast<const unsigned char *>(data->hints),
+ sizeof(wauthn_pubkey_cred_hint_e));
}
void WAuthnCtypeSerializer::deserialize(IStream& stream, wauthn_pubkey_cred_hints_s** data) {
// Deserialize struct itself
}
__checkValidity(*data);
// Deserialize 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));
- __checkValidity(tmp);
- if (i == 0) // set pointer to the first parameter
- (*data)->hints = tmp;
- }
+ __deserializeArray(stream, (*data)->size, reinterpret_cast<unsigned char **>(&((*data)->hints)),
+ sizeof(wauthn_pubkey_cred_hint_e));
+
+ __checkAlignment("wauthn_pubkey_cred_hints_s->hints", (*data)->hints);
}
// For wauthn_hybrid_linked_data_s
+void __checkAlignment(const wauthn_hybrid_linked_data_s* data) {
+ __checkAlignment("wauthn_hybrid_linked_data_s->contact_id", data->contact_id);
+ __checkAlignment("wauthn_hybrid_linked_data_s->link_id", data->link_id);
+ __checkAlignment("wauthn_hybrid_linked_data_s->link_secret", data->link_secret);
+ __checkAlignment("wauthn_hybrid_linked_data_s->authenticator_pubkey", data->authenticator_pubkey);
+ __checkAlignment("wauthn_hybrid_linked_data_s->authenticator_name", data->authenticator_name);
+ __checkAlignment("wauthn_hybrid_linked_data_s->signature", data->signature);
+ __checkAlignment("wauthn_hybrid_linked_data_s->tunnel_server_domain", data->tunnel_server_domain);
+ __checkAlignment("wauthn_hybrid_linked_data_s->identity_key", data->identity_key);
+}
void WAuthnCtypeSerializer::serialize(IStream& stream, const wauthn_hybrid_linked_data_s* data) {
// Serialize struct itself
serializeStructBody(stream, reinterpret_cast<const void *>(data), sizeof(wauthn_hybrid_linked_data_s));
deserialize(stream, &((*data)->signature));
deserialize(stream, &((*data)->tunnel_server_domain));
deserialize(stream, &((*data)->identity_key));
+
+ __checkAlignment(*data);
}
// For 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_const_buffer_s));
+ __serializeArray(stream, data->size, reinterpret_cast<const unsigned char *>(data->attestation_formats),
+ sizeof(wauthn_const_buffer_s));
// Serialize the contents of pointers in struct array
for(size_t i=0; i < data->size; i++ )
__serializePointerContents(stream, data->attestation_formats + i);
}
__checkValidity(*data);
// Deserialize array
- wauthn_const_buffer_s* tmp;
- for(size_t i=0; i < (*data)->size; i++ ) {
- __deserializeArrayItem(stream, reinterpret_cast<void **>(&tmp), sizeof(wauthn_const_buffer_s));
- if (i == 0) // set pointer to the first parameter
- (*data)->attestation_formats = tmp;
- }
+ __deserializeArray(stream, (*data)->size, reinterpret_cast<unsigned char **>(&((*data)->attestation_formats)),
+ sizeof(wauthn_const_buffer_s));
// Deserialize the contents of pointers in struct array
for(size_t i=0; i < (*data)->size; i++ )
__deserializePointerContents(stream, (*data)->attestation_formats + i);
+
+ __checkAlignment("wauthn_attestation_formats_s->attestation_formats", (*data)->attestation_formats);
}
// For wauthn_pubkey_cred_creation_options_s
+void __checkAlignment(const wauthn_pubkey_cred_creation_options_s* data) {
+ __checkAlignment("wauthn_pubkey_cred_creation_options_s->rp", data->rp);
+ __checkAlignment("wauthn_pubkey_cred_creation_options_s->user", data->user);
+ __checkAlignment("wauthn_pubkey_cred_creation_options_s->pubkey_cred_params", data->pubkey_cred_params);
+ __checkAlignment("wauthn_pubkey_cred_creation_options_s->exclude_credentials", data->exclude_credentials);
+ __checkAlignment("wauthn_pubkey_cred_creation_options_s->authenticator_selection", data->authenticator_selection);
+ __checkAlignment("wauthn_pubkey_cred_creation_options_s->hints", data->hints);
+ __checkAlignment("wauthn_pubkey_cred_creation_options_s->attestation_formats", data->attestation_formats);
+ __checkAlignment("wauthn_pubkey_cred_creation_options_s->extensions", data->extensions);
+ __checkAlignment("wauthn_pubkey_cred_creation_options_s->linked_device", data->linked_device);
+}
void __checkValidity(wauthn_attestation_pref_e attestation) {
switch(attestation) {
case WAUTHN_ATTESTATION_PREF_NONE:
deserialize(stream, &((*data)->attestation_formats));
deserialize(stream, &((*data)->extensions));
deserialize(stream, &((*data)->linked_device));
+
+ __checkAlignment(*data);
}
// For wauthn_pubkey_cred_request_options_s
+void __checkAlignment(const wauthn_pubkey_cred_request_options_s* data) {
+ __checkAlignment("wauthn_pubkey_cred_request_options_s->rpId", data->rpId);
+ __checkAlignment("wauthn_pubkey_cred_request_options_s->allow_credentials", data->allow_credentials);
+ __checkAlignment("wauthn_pubkey_cred_request_options_s->hints", data->hints);
+ __checkAlignment("wauthn_pubkey_cred_request_options_s->attestation_formats", data->attestation_formats);
+ __checkAlignment("wauthn_pubkey_cred_request_options_s->extensions", data->extensions);
+ __checkAlignment("wauthn_pubkey_cred_request_options_s->linked_device", data->linked_device);
+}
void __checkValidity(const wauthn_pubkey_cred_request_options_s* data) {
if (data == nullptr)
return;
deserialize(stream, &((*data)->attestation_formats));
deserialize(stream, &((*data)->extensions));
deserialize(stream, &((*data)->linked_device));
+
+ __checkAlignment(*data);
}
// For wauthn_pubkey_credential_attestation_s
+void __checkAlignment(const wauthn_pubkey_credential_attestation_s* data) {
+ __checkAlignment("wauthn_pubkey_credential_attestation_s->id", data->id);
+ __checkAlignment("wauthn_pubkey_credential_attestation_s->rawId", data->rawId);
+ __checkAlignment("wauthn_pubkey_credential_attestation_s->response", data->response);
+ __checkAlignment("wauthn_pubkey_credential_attestation_s->extensions", data->extensions);
+ __checkAlignment("wauthn_pubkey_credential_attestation_s->linked_device", data->linked_device);
+}
void __checkValidity(const wauthn_pubkey_credential_attestation_s* data) {
if (data == nullptr)
return;
deserialize(stream, &((*data)->response));
deserialize(stream, &((*data)->extensions));
deserialize(stream, &((*data)->linked_device));
+
+ __checkAlignment(*data);
}
// For wauthn_pubkey_credential_assertion_s
+void __checkAlignment(const wauthn_pubkey_credential_assertion_s* data) {
+ __checkAlignment("wauthn_pubkey_credential_assertion_s->id", data->id);
+ __checkAlignment("wauthn_pubkey_credential_assertion_s->rawId", data->rawId);
+ __checkAlignment("wauthn_pubkey_credential_assertion_s->response", data->response);
+ __checkAlignment("wauthn_pubkey_credential_assertion_s->extensions", data->extensions);
+ __checkAlignment("wauthn_pubkey_credential_assertion_s->linked_device", data->linked_device);
+}
void __checkValidity(const wauthn_pubkey_credential_assertion_s* data) {
if (data == nullptr)
return;
deserialize(stream, &((*data)->response));
deserialize(stream, &((*data)->extensions));
deserialize(stream, &((*data)->linked_device));
+
+ __checkAlignment(*data);
}
// For wauthn_client_data_s
__checkValidity(*data);
// Deserialize the contents of struct's pointers
deserialize(stream, &((*data)->client_data_json));
+
+ __checkAlignment("wauthn_client_data_s->client_data_json", (*data)->client_data_json);
}