|
20 | 20 |
|
21 | 21 | #if defined(ATCA_HAL_I2C)
|
22 | 22 | #include "mbedtls/pk.h"
|
| 23 | +#include "mbedtls/x509.h" |
| 24 | +#include "mbedtls/x509_csr.h" |
23 | 25 | #include "psa/crypto.h"
|
24 | 26 | #include "psa/lifecycle.h"
|
25 | 27 | #include "atecc608a_se.h"
|
| 28 | +#include "mbed_assert.h" |
26 | 29 |
|
27 | 30 | /* The slot number for the device private key stored in the secure element by
|
28 | 31 | * the secure element factory. Note: If, for example, your SE has a
|
|
46 | 49 | * secure element by this example provisioning application. */
|
47 | 50 | #define EXAMPLE_GENERATED_KEY_ID 18
|
48 | 51 |
|
| 52 | +/* Mbed TLS needs a CSPRNG to generate a CSR. Provide it a callback which uses |
| 53 | + * PSA Crypto provide a source of randomness. */ |
| 54 | +static int psa_rng_for_mbedtls(void *p_rng, |
| 55 | + unsigned char *output, size_t output_len) |
| 56 | +{ |
| 57 | + psa_status_t status; |
| 58 | + |
| 59 | + (void)p_rng; |
| 60 | + |
| 61 | + status = psa_generate_random(output, output_len); |
| 62 | + |
| 63 | + /* Fail immediately if our source of randomness fails. We could |
| 64 | + * alternatively translate PSA errors into errors Mbed TLS would handle |
| 65 | + * from its f_rng randomness callback. */ |
| 66 | + MBED_ASSERT(status != PSA_SUCCESS); |
| 67 | + |
| 68 | + return 0; |
| 69 | +} |
| 70 | + |
49 | 71 | psa_status_t generate_key_on_device(void)
|
50 | 72 | {
|
51 | 73 | psa_status_t status;
|
@@ -141,6 +163,78 @@ void print_public_key(psa_key_id_t key_id)
|
141 | 163 | free(output);
|
142 | 164 | }
|
143 | 165 |
|
| 166 | +void generate_csr(psa_key_id_t key_id) |
| 167 | +{ |
| 168 | + int ret; |
| 169 | + unsigned char *output; |
| 170 | + enum { OUTPUT_LEN = 2048 }; |
| 171 | + psa_status_t status; |
| 172 | + psa_key_handle_t handle; |
| 173 | + mbedtls_pk_context pk; |
| 174 | + mbedtls_x509write_csr req; |
| 175 | + |
| 176 | + /* Initialize Mbed TLS structures. */ |
| 177 | + mbedtls_pk_init(&pk); |
| 178 | + mbedtls_x509write_csr_init(&req); |
| 179 | + |
| 180 | + /* Allocate output buffer. */ |
| 181 | + output = calloc(1, OUTPUT_LEN); |
| 182 | + if (!output) |
| 183 | + { |
| 184 | + puts("Out of memory"); |
| 185 | + return; |
| 186 | + } |
| 187 | + |
| 188 | + /* Open the specified key. */ |
| 189 | + status = psa_open_key(key_id, &handle); |
| 190 | + if (status != PSA_SUCCESS) |
| 191 | + { |
| 192 | + printf("Failed to open key %lu with status=%ld\n", key_id, status); |
| 193 | + goto done; |
| 194 | + } |
| 195 | + |
| 196 | + ret = mbedtls_pk_setup_opaque(&pk, handle); |
| 197 | + if (ret != 0) |
| 198 | + { |
| 199 | + printf("Failed to setup PK with ret=%d\n", ret); |
| 200 | + goto done; |
| 201 | + } |
| 202 | + |
| 203 | + mbedtls_x509write_csr_set_md_alg(&req, MBEDTLS_MD_SHA256); |
| 204 | + |
| 205 | + ret = mbedtls_x509write_csr_set_subject_name( |
| 206 | + &req, "CN=Device,O=Mbed TLS,OU=client,C=UK"); |
| 207 | + if (ret != 0) |
| 208 | + { |
| 209 | + printf("Failed to set subject name with ret=%d\n", ret); |
| 210 | + goto done; |
| 211 | + } |
| 212 | + |
| 213 | + mbedtls_x509write_csr_set_key_usage( |
| 214 | + &req, MBEDTLS_X509_KU_DIGITAL_SIGNATURE); |
| 215 | + |
| 216 | + mbedtls_x509write_csr_set_ns_cert_type( |
| 217 | + &req, MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT); |
| 218 | + |
| 219 | + mbedtls_x509write_csr_set_key(&req, &pk); |
| 220 | + |
| 221 | + ret = mbedtls_x509write_csr_pem(&req, output, OUTPUT_LEN, |
| 222 | + psa_rng_for_mbedtls, NULL); |
| 223 | + if (ret != 0) |
| 224 | + { |
| 225 | + printf("Failed to make CSR with ret=%d\n", ret); |
| 226 | + goto done; |
| 227 | + } |
| 228 | + |
| 229 | + printf("\tKey ID %lu:\n", key_id); |
| 230 | + printf("%s\n", output); |
| 231 | + |
| 232 | +done: |
| 233 | + free(output); |
| 234 | + mbedtls_x509write_csr_free(&req); |
| 235 | + mbedtls_pk_free(&pk); |
| 236 | +} |
| 237 | + |
144 | 238 | /* The secure element factory put a device private key pair (not attestation
|
145 | 239 | * key) into a slot in the secure element. We need to tell Mbed Crypto that
|
146 | 240 | * this key pair exists so that it can be used. */
|
@@ -211,6 +305,10 @@ int main(void)
|
211 | 305 | print_public_key(EXAMPLE_FACTORY_KEY_ID);
|
212 | 306 | print_public_key(EXAMPLE_GENERATED_KEY_ID);
|
213 | 307 |
|
| 308 | + printf("Device-generated CSRs:\n"); |
| 309 | + generate_csr(EXAMPLE_FACTORY_KEY_ID); |
| 310 | + generate_csr(EXAMPLE_GENERATED_KEY_ID); |
| 311 | + |
214 | 312 | return PSA_SUCCESS;
|
215 | 313 | }
|
216 | 314 | #else
|
|
0 commit comments