Skip to content

Commit

Permalink
Anjay 1.8.0
Browse files Browse the repository at this point in the history
Features:
- Added get_security_info() handler to fw_update module, enabling
  configuration of security information for PULL-mode downloads over
  encrypted channels
- Added anjay_fw_update_load_security_from_dm() which allows to match
  security information from the Security object based on URI

Bugfixes:
- fw_update module will no longer connect to any HTTPS or CoAPS URI
  without authentication
  • Loading branch information
Mateusz Kwiatkowski committed Feb 21, 2018
1 parent f48f616 commit ac0f2cd
Show file tree
Hide file tree
Showing 24 changed files with 924 additions and 275 deletions.
6 changes: 4 additions & 2 deletions CMakeLists.txt
Expand Up @@ -26,7 +26,7 @@ if(WITH_FUZZ_TESTS)
endif()

project(anjay C)
set(ANJAY_VERSION "1.7.3" CACHE STRING "Anjay library version")
set(ANJAY_VERSION "1.8.0" CACHE STRING "Anjay library version")
set(ANJAY_BINARY_VERSION 1.0.0)

set(ANJAY_BUILD_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/output")
Expand Down Expand Up @@ -280,9 +280,11 @@ set(CORE_MODULES_HEADERS
include_modules/anjay_modules/io_utils.h
include_modules/anjay_modules/notify.h
include_modules/anjay_modules/observe.h
include_modules/anjay_modules/raw_buffer.h
include_modules/anjay_modules/sched.h
include_modules/anjay_modules/servers.h
include_modules/anjay_modules/time_defs.h
include_modules/anjay_modules/raw_buffer.h)
include_modules/anjay_modules/utils_core.h)
set(CORE_PUBLIC_HEADERS
include_public/anjay/anjay.h
include_public/anjay/core.h
Expand Down
8 changes: 7 additions & 1 deletion demo/demo.c
Expand Up @@ -286,6 +286,11 @@ static int demo_init(anjay_demo_t *demo,
.max_icmp_failures = &cmdline_args->max_icmp_failures,
};

const avs_net_security_info_t *fw_security_info_ptr = NULL;
if (cmdline_args->fw_security_info.mode != (avs_net_security_mode_t) -1) {
fw_security_info_ptr = &cmdline_args->fw_security_info;
}

demo->connection_args = &cmdline_args->connection_args;

demo->anjay = anjay_new(&config);
Expand All @@ -295,7 +300,8 @@ static int demo_init(anjay_demo_t *demo,
|| anjay_attr_storage_install(demo->anjay)
|| anjay_access_control_install(demo->anjay)
|| firmware_update_install(demo->anjay, &demo->fw_update,
cmdline_args->fw_updated_marker_path)
cmdline_args->fw_updated_marker_path,
fw_security_info_ptr)
|| !iosched_poll_entry_new(demo->iosched, STDIN_FILENO,
POLLIN | POLLHUP,
demo_command_dispatch, demo, NULL)) {
Expand Down
119 changes: 113 additions & 6 deletions demo/demo_args.c
Expand Up @@ -47,6 +47,9 @@ static const cmdline_args_t DEFAULT_CMDLINE_ARGS = {
.msg_cache_size = 0,
.fw_updated_marker_path = "/tmp/anjay-fw-updated",
.max_icmp_failures = 7,
.fw_security_info = {
.mode = (avs_net_security_mode_t) -1
},
};

static int parse_security_mode(const char *mode_string,
Expand Down Expand Up @@ -164,10 +167,22 @@ static void print_option_help(const struct option *opt) {
"it to 0 disables caching mechanism." },
{ 'N', NULL, NULL,
"Send notifications as Confirmable messages by default" },
{ 1, "PATH", DEFAULT_CMDLINE_ARGS.fw_updated_marker_path,
"File path to use as a marker for persisting firmware update state" },
{ 'U', "COUNT", "7", "Sets maximum number of ICMP Port/Host unreachable "
"errors before the Server is considered unreachable" },
{ 1, "PATH", DEFAULT_CMDLINE_ARGS.fw_updated_marker_path,
"File path to use as a marker for persisting firmware update state" },
{ 2, "CERT_FILE", NULL, "Require certificate validation against "
"specified file when downloading firmware over encrypted channels" },
{ 3, "CERT_DIR", NULL, "Require certificate validation against files "
"in specified path when downloading firmware over encrypted channels"
"; note that the TLS backend may impose specific requirements for "
"file names and formats" },
{ 4, "PSK identity", NULL, "Download firmware over encrypted channels "
"using PSK-mode encryption with the specified identity (provided as "
"hexlified string); must be used together with --fw-psk-key" },
{ 5, "PSK key", NULL, "Download firmware over encrypted channels using "
"PSK-mode encryption with the specified key (provided as hexlified "
"string); must be used together with --fw-psk-identity" },
};

int description_offset = 25;
Expand Down Expand Up @@ -239,6 +254,9 @@ static int parse_hexstring(const char *str, uint8_t **out, size_t *out_size) {
if (length % 2 || !length) {
return -1;
}
if (*out) {
return -1;
}
*out = (uint8_t *) malloc(length / 2);
*out_size = 0;
if (!*out) {
Expand Down Expand Up @@ -367,8 +385,12 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
{ "outbuf-size", required_argument, 0, 'O' },
{ "cache-size", required_argument, 0, '$' },
{ "confirmable-notifications", no_argument, 0, 'N' },
{ "fw-updated-marker-path", required_argument, 0, 1 },
{ "max-icmp-failures", required_argument, 0, 'U' },
{ "fw-updated-marker-path", required_argument, 0, 1 },
{ "fw-cert-file", required_argument, 0, 2 },
{ "fw-cert-path", required_argument, 0, 3 },
{ "fw-psk-identity", required_argument, 0, 4 },
{ "fw-psk-key", required_argument, 0, 5 },
{ 0, 0, 0, 0 }
};
int num_servers = 0;
Expand Down Expand Up @@ -565,9 +587,6 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
case 'N':
parsed_args->confirmable_notifications = true;
break;
case 1:
parsed_args->fw_updated_marker_path = optarg;
break;
case 'U': {
int32_t max_icmp_failures;
if (parse_i32(optarg, &max_icmp_failures)
Expand All @@ -577,6 +596,87 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
parsed_args->max_icmp_failures = (uint32_t)max_icmp_failures;
break;
}
case 1:
parsed_args->fw_updated_marker_path = optarg;
break;
case 2:
if (parsed_args->fw_security_info.mode
!= (avs_net_security_mode_t) -1) {
demo_log(ERROR, "Multiple incompatible security information "
"specified for firmware upgrade");
goto error;
}
parsed_args->fw_security_info =
avs_net_security_info_from_certificates(
(avs_net_certificate_info_t) {
.server_cert_validation = true,
.trusted_certs =
avs_net_trusted_cert_source_from_paths(
NULL, optarg)
});
break;
case 3:
if (parsed_args->fw_security_info.mode
!= (avs_net_security_mode_t) -1) {
demo_log(ERROR, "Multiple incompatible security information "
"specified for firmware upgrade");
goto error;
}
parsed_args->fw_security_info =
avs_net_security_info_from_certificates(
(avs_net_certificate_info_t) {
.server_cert_validation = true,
.trusted_certs =
avs_net_trusted_cert_source_from_paths(
optarg, NULL)
});
break;
case 4:
if (parsed_args->fw_security_info.mode != AVS_NET_SECURITY_PSK
&& parsed_args->fw_security_info.mode
!= (avs_net_security_mode_t) -1) {
demo_log(ERROR, "Multiple incompatible security information "
"specified for firmware upgrade");
goto error;
}
if (parsed_args->fw_security_info.mode == AVS_NET_SECURITY_PSK
&& parsed_args->fw_security_info.data.psk.identity) {
demo_log(ERROR, "--fw-psk-identity specified more than once");
goto error;
}
if (parse_hexstring(
optarg,
(uint8_t **) (intptr_t)
&parsed_args->fw_security_info.data.psk.identity,
&parsed_args->fw_security_info.data.psk.identity_size)) {
demo_log(ERROR, "Invalid PSK identity for firmware upgrade");
goto error;
}
parsed_args->fw_security_info.mode = AVS_NET_SECURITY_PSK;
break;
case 5:
if (parsed_args->fw_security_info.mode != AVS_NET_SECURITY_PSK
&& parsed_args->fw_security_info.mode
!= (avs_net_security_mode_t) -1) {
demo_log(ERROR, "Multiple incompatible security information "
"specified for firmware upgrade");
goto error;
}
if (parsed_args->fw_security_info.mode == AVS_NET_SECURITY_PSK
&& parsed_args->fw_security_info.data.psk.psk) {
demo_log(ERROR, "--fw-psk-key specified more than once");
goto error;
}
if (parse_hexstring(
optarg,
(uint8_t **) (intptr_t)
&parsed_args->fw_security_info.data.psk.psk,
&parsed_args->fw_security_info.data.psk.psk_size)) {
demo_log(ERROR, "Invalid pre-shared key for firmware upgrade");
goto error;
}
parsed_args->fw_security_info.mode = AVS_NET_SECURITY_PSK;
break;
case 0:
goto finish;
}
Expand Down Expand Up @@ -646,6 +746,13 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
}
}
}
if (parsed_args->fw_security_info.mode == AVS_NET_SECURITY_PSK
&& (!parsed_args->fw_security_info.data.psk.identity
|| !parsed_args->fw_security_info.data.psk.psk)) {
demo_log(ERROR, "Both identity and key must be provided when using PSK "
"for firmware upgrade security");
goto error;
}
return 0;
error:
AVS_LIST_CLEAR(&parsed_args->access_entries);
Expand Down
1 change: 1 addition & 0 deletions demo/demo_args.h
Expand Up @@ -41,6 +41,7 @@ typedef struct cmdline_args {
bool confirmable_notifications;
const char *fw_updated_marker_path;
uint32_t max_icmp_failures;
avs_net_security_info_t fw_security_info;
} cmdline_args_t;

int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char **argv);
Expand Down
20 changes: 18 additions & 2 deletions demo/firmware_update.c
Expand Up @@ -498,7 +498,16 @@ static int fw_perform_upgrade(void *fw_) {
return -1;
}

static const anjay_fw_update_handlers_t FW_UPDATE_HANDLERS = {
static int fw_get_security_info(void *fw_,
avs_net_security_info_t *out_security_info,
const char *download_uri) {
fw_update_logic_t *fw = (fw_update_logic_t *) fw_;
(void) download_uri;
memcpy(out_security_info, &fw->security_info, sizeof(fw->security_info));
return 0;
}

static anjay_fw_update_handlers_t FW_UPDATE_HANDLERS = {
.stream_open = fw_stream_open,
.stream_write = fw_stream_write,
.stream_finish = fw_stream_finish,
Expand Down Expand Up @@ -585,8 +594,15 @@ static persistence_file_data_t read_persistence_file(const char *path) {

int firmware_update_install(anjay_t *anjay,
fw_update_logic_t *fw,
const char *persistence_file) {
const char *persistence_file,
const avs_net_security_info_t *security_info) {
fw->persistence_file = persistence_file;
if (security_info) {
memcpy(&fw->security_info, security_info, sizeof(fw->security_info));
FW_UPDATE_HANDLERS.get_security_info = fw_get_security_info;
} else {
FW_UPDATE_HANDLERS.get_security_info = NULL;
}

persistence_file_data_t data = read_persistence_file(persistence_file);
delete_persistence_file(fw);
Expand Down
4 changes: 3 additions & 1 deletion demo/firmware_update.h
Expand Up @@ -35,11 +35,13 @@ typedef struct {
char *package_uri;
const char *persistence_file;
FILE *stream;
avs_net_security_info_t security_info;
} fw_update_logic_t;

int firmware_update_install(anjay_t *anjay,
fw_update_logic_t *fw,
const char *persistence_file);
const char *persistence_file,
const avs_net_security_info_t *security_info);

void firmware_update_destroy(fw_update_logic_t *fw_update);

Expand Down
9 changes: 8 additions & 1 deletion include_modules/anjay_modules/downloader.h
Expand Up @@ -21,7 +21,14 @@

VISIBILITY_PRIVATE_HEADER_BEGIN

bool _anjay_downloader_protocol_supported(const char *proto);
typedef enum {
ANJAY_DOWNLOADER_PROTO_UNSUPPORTED,
ANJAY_DOWNLOADER_PROTO_PLAIN,
ANJAY_DOWNLOADER_PROTO_ENCRYPTED
} anjay_downloader_protocol_class_t;

anjay_downloader_protocol_class_t
_anjay_downloader_classify_protocol(const char *proto);

VISIBILITY_PRIVATE_HEADER_END

Expand Down
53 changes: 53 additions & 0 deletions include_modules/anjay_modules/servers.h
@@ -0,0 +1,53 @@
/*
* Copyright 2017-2018 AVSystem <avsystem@avsystem.com>
*
* 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.
*/

#ifndef ANJAY_INCLUDE_ANJAY_MODULES_SERVERS_H
#define ANJAY_INCLUDE_ANJAY_MODULES_SERVERS_H

#include <anjay/core.h>

#include <anjay_modules/utils_core.h>

VISIBILITY_PRIVATE_HEADER_BEGIN

typedef enum {
ANJAY_CONNECTION_UDP,
ANJAY_CONNECTION_SMS,
ANJAY_CONNECTION_UNSET
} anjay_connection_type_t;

typedef struct {
char pk_or_identity[ANJAY_MAX_PK_OR_IDENTITY_SIZE];
size_t pk_or_identity_size;
char server_pk_or_identity[ANJAY_MAX_SERVER_PK_OR_IDENTITY_SIZE];
size_t server_pk_or_identity_size;
char secret_key[ANJAY_MAX_SECRET_KEY_SIZE];
size_t secret_key_size;
} anjay_server_dtls_keys_t;

int _anjay_server_get_uri(anjay_t *anjay,
anjay_iid_t security_iid,
anjay_url_t *out_uri);

int _anjay_get_security_info(anjay_t *anjay,
avs_net_security_info_t *out_net_info,
anjay_server_dtls_keys_t *out_dtls_keys,
anjay_iid_t security_iid,
anjay_connection_type_t conn_type);

VISIBILITY_PRIVATE_HEADER_END

#endif /* ANJAY_INCLUDE_ANJAY_MODULES_SERVERS_H */

0 comments on commit ac0f2cd

Please sign in to comment.