void IoTService::authenticateMessage(boost::asio::ip::address_v6 senderAddress, std::vector<uint8_t> data, ec taKey) { LOG(INFO) << "CBOR decode message..."; Signature sig; std::vector<uint8_t> message; std::array<uint8_t, 16> senderBytes = senderAddress.to_bytes(); std::vector<uint8_t> senderBytesVec(senderBytes.begin(), senderBytes.end()); struct cbor_load_result result; cbor_item_t* item = cbor_load(data.data(), data.size(), &result); size_t pairs = cbor_map_size(item); for (cbor_pair* pair = cbor_map_handle(item); pairs > 0; pair++, pairs--) { if (strncmp(reinterpret_cast<char*>(cbor_string_handle(pair->key)), "sig", 3) == 0) { sig = Signature::fromCBORArray(pair->value); } else if (strncmp(reinterpret_cast<char*>(cbor_string_handle(pair->key)), "msg", 3) == 0) { size_t length = cbor_bytestring_length(pair->value); message = std::vector<uint8_t>(cbor_bytestring_handle(pair->value), cbor_bytestring_handle(pair->value) + length); } } LOG(INFO) << "Authenticating message..."; bool sigCorrect = Signature::verify(senderBytesVec, message, taKey.p, sig); if (sigCorrect) { LOG(INFO) << "Signature correct: msg: " << byteVecToStr(message); } else { LOG(INFO) << "Signature invalid."; } }
size_t cbor_serialize_string(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) { assert(cbor_isa_string(item)); if (cbor_string_is_definite(item)) { size_t length = cbor_string_length(item); size_t written = cbor_encode_string_start(length, buffer, buffer_size); if (written && (buffer_size - written >= length)) { memcpy(buffer + written, cbor_string_handle(item), length); return written + length; } else return 0; } else { assert(cbor_string_is_indefinite(item)); size_t chunk_count = cbor_string_chunk_count(item); size_t written = cbor_encode_indef_string_start(buffer, buffer_size); if (written == 0) return 0; cbor_item_t **chunks = cbor_string_chunks_handle(item); for (size_t i = 0; i < chunk_count; i++) { size_t chunk_written = cbor_serialize_string(chunks[i], buffer + written, buffer_size - written); if (chunk_written == 0) return 0; else written += chunk_written; } if (cbor_encode_break(buffer + written, buffer_size - written) > 0) return written + 1; else return 0; } }
void DynamicConfigurationServer::handleRequestReceived(const boost::system::error_code& error, size_t bytes_transferred) { LOG(INFO) << "Request received from " << remote_endpoint_; LOG(INFO) << "Begin CBOR decoding"; struct cbor_load_result result; cbor_item_t* item = cbor_load((uint8_t*)recv_buffer_.data(), bytes_transferred, &result); size_t items = cbor_array_size(item); assert(items == 2); cbor_item_t* nonceItem = cbor_array_get(item, 0); cbor_item_t* ciphertextItem = cbor_array_get(item, 1); //cbor_describe(item, stdout); //fflush(stdout); std::array<uint8_t, 16> nonce; memcpy(nonce.data(), cbor_bytestring_handle(nonceItem), 16); std::vector<uint8_t> ciphertext; ciphertext.resize(cbor_bytestring_length(ciphertextItem)); memcpy(ciphertext.data(), cbor_bytestring_handle(ciphertextItem), ciphertext.size()); std::array<uint8_t, 16> requestKey; memcpy(requestKey.data(), confRequestKey, 16); LOG(INFO) << "End CBOR decoding"; LOG(INFO) << "Begin NORX decryption"; std::tuple<bool, std::vector<uint8_t> > plaintext = NORX::decrypt( std::vector<uint8_t>(), ciphertext, std::vector<uint8_t>(), nonce, requestKey); LOG(INFO) << "END NORX decryption"; cbor_decref(&item); if (std::get<0>(plaintext)) { LOG(INFO) << "decryption successful"; item = cbor_load((uint8_t*)std::get<1>(plaintext).data(), std::get<1>(plaintext).size(), &result); //LOG(INFO) << "plaintext: " << byteVecToStr(std::get<1>(plaintext)); if (strncmp("REQ", (const char*)cbor_string_handle(item), 3) == 0) { LOG(INFO) << "received correct request"; generateCredentialsAndSendResponse(nonce); } else { cbor_describe(item, stdout); } fflush(stdout); /* Deallocate the result */ cbor_decref(&item); } else { LOG(ERROR) << "failed decrypting dynamic initialisation request."; LOG(ERROR) << "ciphertext: " << byteVecToStr(ciphertext); LOG(ERROR) << "nonce: " << byteVecToStr(std::vector<uint8_t>(nonce.begin(), nonce.end())); } startReceive(); }