-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Track container/guestOS CAs as symlink #332
base: kirkstone
Are you sure you want to change the base?
Conversation
64179a6
to
5fce586
Compare
daemon/cmld.c
Outdated
@@ -418,13 +418,15 @@ cmld_container_new(const char *store_path, const uuid_t *existing_uuid, const ui | |||
/******************************** | |||
* Translate High Level Config into low-level parameters for internal | |||
* constructor */ | |||
char *ca_symlink_path = guestos_get_ca_file_new(images_dir); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd suggest moving this up next to "config_filename = " and adding a DEBUG statement as for config_filename and images_dir
daemon/cmld.c
Outdated
container_config_t *conf = container_config_new(config_filename, config, config_len, sig, | ||
sig_len, cert, cert_len); | ||
sig_len, cert, cert_len, ca_symlink_path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of adding a parameter to container_config_new requireing on memory allocation on each calling funtion,
i'd suggest to generate the CA path in container_config_new using the container_dir+UUID path ('prefix' variable)
daemon/container_config.c
Outdated
@@ -176,7 +177,7 @@ container_config_verify(const char *prefix, uint8_t *conf_buf, size_t conf_len, | |||
|
|||
container_config_t * | |||
container_config_new(const char *file, const uint8_t *buf, size_t len, uint8_t *sig_buf, | |||
size_t sig_len, uint8_t *cert_buf, size_t cert_len) | |||
size_t sig_len, uint8_t *cert_buf, size_t cert_len, const char *ca_symlink) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above
daemon/container_config.c
Outdated
@@ -111,7 +111,7 @@ container_config_proto_to_usb_type(ContainerUsbType type) | |||
*/ | |||
static bool | |||
container_config_verify(const char *prefix, uint8_t *conf_buf, size_t conf_len, uint8_t *sig_buf, | |||
size_t sig_len, uint8_t *cert_buf, size_t cert_len) | |||
size_t sig_len, uint8_t *cert_buf, size_t cert_len, const char *ca_symlink) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like for config_config_new, 'prefix" contains the necessary information, i'd suggest not to extend the function signature here
|
||
//read Path to CA from old_os_ca_symlink | ||
if (readlink(old_os_ca_symlink, old_os_ca_path, sizeof(old_os_ca_path)) < 0) { | ||
ERROR("Symlink destination of %s could not been read. Creating new symlink not possible.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
severe ERROR, new GuestOS installation should be aborted in this case
(+ add mem_frees before early return)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
//update ca symlink name | ||
if (symlink(old_os_ca_path, new_os_ca_symlink)) { | ||
ERROR("FAILED to create symlink %s -> %s.", new_os_ca_symlink, | ||
old_os_ca_path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
severe error, see above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
daemon/guestos_mgr.c
Outdated
@@ -518,9 +542,23 @@ guestos_mgr_push_config(unsigned char *cfg, size_t cfglen, unsigned char *sig, s | |||
audit_log_event(NULL, FSA, CMLD, GUESTOS_MGMT, "push-os-missing-certificate", | |||
guestos_basepath, 0); | |||
} else { | |||
res = crypto_verify_buf(cfg, cfglen, sig, siglen, cert, certlen, | |||
//Construct os to get CA filepath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typos
daemon/guestos_mgr.c
Outdated
@@ -518,9 +542,23 @@ guestos_mgr_push_config(unsigned char *cfg, size_t cfglen, unsigned char *sig, s | |||
audit_log_event(NULL, FSA, CMLD, GUESTOS_MGMT, "push-os-missing-certificate", | |||
guestos_basepath, 0); | |||
} else { | |||
res = crypto_verify_buf(cfg, cfglen, sig, siglen, cert, certlen, | |||
//Construct os to get CA filepath | |||
guestos_t *os = guestos_new_from_buffer(cfg, cfglen, guestos_basepath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This parses unverified data => buffer can be parsed after successful signature verification only.
We should either stick with current approach in the SCD and do symlink processing based on the returned CA or pass the CA path if already exiting => let's discuss this
daemon/scd.proto
Outdated
@@ -159,5 +160,6 @@ message TokenToDaemon { | |||
|
|||
optional bytes device_csr = 40; // device csr in response to PULL_CSR | |||
optional bytes hash_value = 50; // hash_value in reponse to CRYPTO_HASH_FILE | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--
can you be a little bit more verbose in the commit messages. The commit heading should, be short Thnx, |
…rom first successful verification as symlink After the first successful signature verification of a guestos or container, a symlink pointing to the CA used for verification is created. In case of an update to the entity, it is checked whether the CA remains unchanged. If the update was signed using a different PKI, the update is rejected, even if the CA is known to the system. To achieve this, crypto_verify_result_t is extended to contain the path of the CA used for verification. The path is provided by scd during signature verification. If there has not been a symlink for the container/guestos under verification, cmld creates a symlink to the path given in crypto_verify_result_t. If there already is a symlink available, cmld compares the destination of the symlink against the CA given in the result. If they do not match, the verification is considered failed. Signed-off-by: Corinna Lingstädt <[email protected]>
Signed-off-by: Corinna Lingstädt <[email protected]>
Signed-off-by: Corinna Lingstädt <[email protected]>
@@ -223,6 +223,8 @@ crypto_cb(int fd, unsigned events, event_io_t *io, void *data) | |||
|
|||
TRACE("Received message crypto msg from SCD"); | |||
|
|||
crypto_verify_result_t verify_result = { .code = VERIFY_ERROR, .matched_ca = str_new("") }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imho .matched_ca should only be initialized if a matching CA is actually found.
If there was a VERIFY_ERROR it's ok for .matched_ca to be NULL.
ERROR("TokenToDaemon ca_path null after successful verification"); | ||
break; | ||
} else { | ||
str_append(verify_result.matched_ca, msg->ca_path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above, would use str_new here in case a matching CA was returned
@@ -531,7 +541,7 @@ crypto_verify_file_block(const char *datafile, const char *sigfile, const char * | |||
ASSERT(sigfile); | |||
ASSERT(certfile); | |||
|
|||
crypto_verify_result_t ret = VERIFY_ERROR; | |||
crypto_verify_result_t ret = { .code = VERIFY_ERROR, .matched_ca = str_new("") }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above, should imho only be initialized if a CA was actually returned
ret = crypto_verify_result_from_proto(msg->code); | ||
ret.code = crypto_verify_result_from_proto(msg->code); | ||
if (msg->ca_path != NULL) { | ||
str_append(ret.matched_ca, msg->ca_path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above, would use str_new here
@@ -578,7 +595,7 @@ crypto_verify_buf_block(unsigned char *data_buf, size_t data_buf_len, unsigned c | |||
ASSERT(sig_buf); | |||
ASSERT(cert_buf); | |||
|
|||
crypto_verify_result_t ret = VERIFY_ERROR; | |||
crypto_verify_result_t ret = { .code = VERIFY_ERROR, .matched_ca = str_new("") }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above
@@ -119,6 +121,9 @@ scd_control_verify_cert_ca_cb(const char *path, const char *file, void *data) | |||
} else { | |||
INFO("Certificate validation succeeded using ca: %s", ca_file); | |||
cb_data->verified = true; | |||
//Give back path to successful CA | |||
str_append(cb_data->ca_path, ca_file); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be str_new?
{ | ||
ASSERT(verify_ca_file); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should return an error code instead of ASSERTing (analogously to other pointer arguments passed to ssl_verify_cert below)
// At first, we explicitly assume that the file to be verified is a software update file, | ||
// and we thus use the software signing root CA. | ||
if ((ret = ssl_verify_certificate(verify_cert_file, SSIG_ROOT_CERT, ignore_time)) == 0) { | ||
verified = true; | ||
|
||
//track matched CA | ||
str_append(verify_ca_file, SSIG_ROOT_CERT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imho we should return a pointer (possibly via a str_t** parameter)
@@ -166,6 +177,7 @@ scd_control_handle_verify(const char *verify_data_file, const char *verify_sig_f | |||
|
|||
// Retry with Local CA | |||
if ((ret = ssl_verify_certificate(verify_cert_file, LOCALCA_ROOT_CERT, ignore_time)) == 0) { | |||
str_append(verify_ca_file, LOCALCA_ROOT_CERT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above
@@ -529,6 +545,12 @@ scd_control_handle_message(const DaemonToToken *msg, int fd) | |||
unlink(tmp_cert_file); | |||
mem_free0(tmp_cert_file); | |||
} | |||
if (out.ca_path) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plz verify value assigned by TOKEN_TO_DAEMON__INIT to ensure NULL is assigned to out.ca_path
|
We create a symlink to the CA which successfully verified a container/guestos for the first time. If the container/guestos is updated, only updates signed with the same CA will be accepted.
Apart from that, there are two small bug fixes.