-
Notifications
You must be signed in to change notification settings - Fork 19
Move hardcoded certificates from Golioth subsystem into samples #398
Conversation
Visit the preview URL for this PR (updated for commit bee50d8): https://golioth-zephyr-sdk-doxygen-dev--pr398-certificate-prov-egk9u7x2.web.app (expires Wed, 28 Jun 2023 17:07:23 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: a389eefadf4b4b68a539327b3459dd66c142cf49 |
ba9dc5b
to
d567d8b
Compare
foreach(type IN ITEMS ca crt key) | ||
string(TOUPPER ${type} type_upper) | ||
set(path ${CONFIG_GOLIOTH_SYSTEM_CLIENT_${type_upper}_PATH}) | ||
set(path ${CONFIG_GOLIOTH_SYSTEM_CLIENT_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.
The CA cert stays hardcoded in the Golioth library for now because it is the same across the entire fleet. Eventually, we'll need a way to provision this certificate, but that is part of a larger story around rolling the CA certificate that is out of scope of these changes.
d567d8b
to
cbca3fb
Compare
cbca3fb
to
c581432
Compare
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 like the direction this is going to, i.e. decoupling "system client" from TLS credentials.
We need something similar for PSK auth as well, so that user (or in our case samples/
implementation) will be responsible for setting credentials.
s/libray/library/
typo in commit message.
It looks like those 2 commits are not bisectable, so probably they should be squashed.
net/golioth/system_client.c
Outdated
int ret = 0; | ||
if (IS_ENABLED(CONFIG_GOLIOTH_AUTH_METHOD_PSK)) { | ||
golioth_settings_check_credentials(); | ||
} else if (IS_ENABLED(CONFIG_GOLIOTH_AUTH_METHOD_CERT)) { | ||
ret = golioth_check_cert_credentials(); | ||
} | ||
|
||
if (ret == 0) { | ||
k_sem_give(&sys_client_started); | ||
} else { | ||
LOG_WRN("Error loading TLS credentials, golioth system client was not started"); |
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.
int ret = 0; | |
if (IS_ENABLED(CONFIG_GOLIOTH_AUTH_METHOD_PSK)) { | |
golioth_settings_check_credentials(); | |
} else if (IS_ENABLED(CONFIG_GOLIOTH_AUTH_METHOD_CERT)) { | |
ret = golioth_check_cert_credentials(); | |
} | |
if (ret == 0) { | |
k_sem_give(&sys_client_started); | |
} else { | |
LOG_WRN("Error loading TLS credentials, golioth system client was not started"); | |
int err = 0; | |
if (IS_ENABLED(CONFIG_GOLIOTH_AUTH_METHOD_PSK)) { | |
golioth_settings_check_credentials(); | |
} else if (IS_ENABLED(CONFIG_GOLIOTH_AUTH_METHOD_CERT)) { | |
err = golioth_check_cert_credentials(); | |
} | |
if (err) { | |
LOG_WRN("Error loading TLS credentials, golioth system client was not started"); | |
} else { | |
k_sem_give(&sys_client_started); |
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 prefer to have the happy path first, and error handling in the else
clause. I'll update to the err
naming to match the rest of the file.
TLS_CREDENTIAL_SERVER_CERTIFICATE, NULL, &cred_len); | ||
if (-ENOENT == err) { | ||
LOG_WRN("Certificate authentication configured, but no client certificate found"); | ||
goto finish; |
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.
goto finish; | |
return err; |
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 prefer to have a single return point from each function. In a small function like this, it doesn't make much difference, but in larger functions it helps to make the code more readable (subjective) and reduces the likelihood of bugs arising from improper cleanup (objective).
TLS_CREDENTIAL_PRIVATE_KEY, NULL, &cred_len); | ||
if (-ENOENT == err) { | ||
LOG_WRN("Certificate authentication configured, but no private key found"); | ||
goto finish; |
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.
goto finish; | |
return err; |
net/golioth/system_client.c
Outdated
size_t cred_len = 0; | ||
int err = tls_credential_get(CONFIG_GOLIOTH_SYSTEM_CLIENT_CREDENTIALS_TAG, | ||
TLS_CREDENTIAL_SERVER_CERTIFICATE, NULL, &cred_len); | ||
if (-ENOENT == err) { |
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.
if (-ENOENT == err) { | |
if (err == -ENOENT) { |
And how about other error codes?
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 was put in specifically to guard against pion/dtls#529 (spent about 30 minutes confused before I remembered that one). I don't think there's value in checking other error codes. Right now, the only other one that is specified in the API is -EACCESS
. This isn't actually returned anywhere in the implementation, but I imagine it's there in the case that a future TLS Credentials subsystem implementation uses a secure storage backend, which could allow writing keys but not reading them, or only allow reading keys from secure code.
Yup. In the PR description I talk about using the same |
c581432
to
3e386eb
Compare
3e386eb
to
c3db7a1
Compare
Clients are now responsible for setting certificates in the TLS Credential subsystem before starting Golioth samples: add support for hardcoded certs in hello sample The hello sample now shows a trivial example of loading certificates from files selected at build time. This does not demonstrate provisioning, but is the simplest way to show clients how to load certificates into the appropriate storage module so that the TLS library can find and use them. It also maintains the same ease-of-use for samples and experimentation. Signed-off-by: Sam Friedman <[email protected]>
c3db7a1
to
bee50d8
Compare
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.
LGTM. I tested this on an ESP32 and it works great!
This PR removes the management of TLS certificates from the Golioth library. Clients are now responsible for setting TLS certificate credentials in the TLS Credential subsystem before starting the Golioth system, as well as persisting them on the device. In order to facilitate prototyping and experimentation, a new
hardcoded_credentials
module has been added tosamples/common
to provide the same functionality that used to be baked directly into the SDK. This gives application developers the flexibility to implement their own provisioning and storage mechanisms, while maintaining the same low-effort experience for users of the samples.Note that this doesn't actually provide any facility for provisioning certificates, it only removes the parts of the SDK that prevented a customer from implementing provisioning themselves. In a future PR, I'll add a sample that shows one way a developer could provision certificates onto the device. This PR was getting larger than I initially expected, so I decided to break it into parts.
Note too that the new
hardcoded_credentials
module is also where I plan to put hardcoded PSK credentials for the samples after we remove that from the SDK. Bringing the hardcoded credentials code up into the samples should make it more obvious to users when they need to set credentials in Kconfig vs provisioned, as well as make the SDK itself cleaner.