Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
attest.c
Go to the documentation of this file.
1/*
2 * Copyright 2015-2018 Yubico AB
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifdef NDEBUG
18#undef NDEBUG
19#endif
20#include <assert.h>
21#include <stdio.h>
22#include <stdint.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include <openssl/pem.h>
27#include <openssl/x509.h>
28
29#include <yubihsm.h>
30
31#include "openssl-compat.h"
32
33#ifndef DEFAULT_CONNECTOR_URL
34#define DEFAULT_CONNECTOR_URL "http://127.0.0.1:12345"
35#endif
36
37const char attestation_template_file[] = "attestation_template.pem";
38const char *key_label = "label";
39const uint8_t password[] = "password";
40
41static void print_extension(X509_EXTENSION *extension) {
42 // Quick and dirty solution for printing extensions
43
44 const uint8_t version[] = {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
45 0x01, 0x82, 0xc4, 0x0a, 0x04, 0x01};
46 const uint8_t serial[] = {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
47 0x01, 0x82, 0xc4, 0x0a, 0x04, 0x02};
48 const uint8_t origin[] = {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
49 0x01, 0x82, 0xc4, 0x0a, 0x04, 0x03};
50 const uint8_t domains[] = {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
51 0x01, 0x82, 0xc4, 0x0a, 0x04, 0x04};
52 const uint8_t capabilities[] = {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
53 0x01, 0x82, 0xc4, 0x0a, 0x04, 0x05};
54 const uint8_t id[] = {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
55 0x01, 0x82, 0xc4, 0x0a, 0x04, 0x06};
56 const uint8_t label[] = {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
57 0x01, 0x82, 0xc4, 0x0a, 0x04, 0x09};
58
59 ASN1_OBJECT *a_object = X509_EXTENSION_get_object(extension);
60 ASN1_OCTET_STRING *a_value = X509_EXTENSION_get_data(extension);
61 uint8_t object[1024];
62 uint8_t *ptr = object;
63 if (i2d_ASN1_OBJECT(a_object, NULL) > 1024) {
64 printf("Extension to long.\n");
65 return;
66 }
67 unsigned int object_len = i2d_ASN1_OBJECT(a_object, &ptr);
68
69 uint8_t value[1024];
70 ptr = value;
71 if (i2d_ASN1_OCTET_STRING(a_value, NULL) > 1024) {
72 printf("Extension value to long.\n");
73 return;
74 }
75 unsigned int value_len = i2d_ASN1_OCTET_STRING(a_value, &ptr);
76
77 if (object_len == sizeof(version) &&
78 memcmp(object, version, sizeof(version)) == 0) {
79 printf("Version:");
80 } else if (object_len == sizeof(serial) &&
81 memcmp(object, serial, sizeof(serial)) == 0) {
82 printf("Serial:");
83 } else if (object_len == sizeof(origin) &&
84 memcmp(object, origin, sizeof(origin)) == 0) {
85 printf("Origin:");
86 } else if (object_len == sizeof(domains) &&
87 memcmp(object, domains, sizeof(domains)) == 0) {
88 printf("Domains:");
89 } else if (object_len == sizeof(capabilities) &&
90 memcmp(object, capabilities, sizeof(capabilities)) == 0) {
91 printf("Capabilities:");
92 } else if (object_len == sizeof(id) && memcmp(object, id, sizeof(id)) == 0) {
93 printf("ID:");
94 } else if (object_len == sizeof(label) &&
95 memcmp(object, label, sizeof(label)) == 0) {
96 printf("Label:");
97 } else {
98 printf("Unknown:");
99 }
100
101 for (unsigned int i = 0; i < value_len; i++) {
102 printf(" %02x", value[i]);
103 }
104 printf("\n");
105}
106
107int main(void) {
108 yh_connector *connector = NULL;
109 yh_session *session = NULL;
111
112 uint16_t authkey = 1;
113
114 const char *connector_url;
115
116 connector_url = getenv("DEFAULT_CONNECTOR_URL");
117 if (connector_url == NULL) {
118 connector_url = DEFAULT_CONNECTOR_URL;
119 }
120
121 yrc = yh_init();
122 assert(yrc == YHR_SUCCESS);
123
124 yrc = yh_init_connector(connector_url, &connector);
125 assert(yrc == YHR_SUCCESS);
126
127 yrc = yh_connect(connector, 0);
128 assert(yrc == YHR_SUCCESS);
129
130 yrc = yh_create_session_derived(connector, authkey, password,
131 sizeof(password), false, &session);
132 assert(yrc == YHR_SUCCESS);
133
135 assert(yrc == YHR_SUCCESS);
136
137 uint8_t session_id;
138 yrc = yh_get_session_id(session, &session_id);
139 assert(yrc == YHR_SUCCESS);
140
141 printf("Successfully established session %02d\n", session_id);
142
144 yrc =
145 yh_string_to_capabilities("sign-attestation-certificate", &capabilities);
146 assert(yrc == YHR_SUCCESS);
147
148 uint16_t domain_five = 0;
149 yrc = yh_string_to_domains("5", &domain_five);
150 assert(yrc == YHR_SUCCESS);
151
152 uint16_t attesting_key_id = 0; // ID 0 lets the device generate an ID
153
154 yrc = yh_util_generate_ec_key(session, &attesting_key_id, key_label,
155 domain_five, &capabilities, YH_ALGO_EC_P256);
156 assert(yrc == YHR_SUCCESS);
157
158 printf("Generated attesting key with ID %04x\n", attesting_key_id);
159
160 FILE *fp = fopen(attestation_template_file, "rb");
161 assert(fp != NULL);
162
163 X509 *attestation_template = PEM_read_X509(fp, NULL, NULL, NULL);
164 assert(attestation_template != NULL);
165 fclose(fp);
166
167 uint8_t attestation_template_buffer[3072];
168 uint16_t attestation_template_buffer_len =
169 i2d_X509(attestation_template, NULL);
170 assert(sizeof(attestation_template_buffer) >=
171 attestation_template_buffer_len);
172
173 unsigned char *certptr = attestation_template_buffer;
174
175 i2d_X509(attestation_template, &certptr);
176 X509_free(attestation_template);
177
179 yrc =
180 yh_util_import_opaque(session, &attesting_key_id, key_label, domain_five,
182 attestation_template_buffer,
183 attestation_template_buffer_len);
184 assert(yrc == YHR_SUCCESS);
185
186 uint8_t tmpbuf[3072];
187 size_t tmpbuf_len = sizeof(tmpbuf);
188 yrc = yh_util_get_opaque(session, attesting_key_id, tmpbuf, &tmpbuf_len);
189 assert(yrc == YHR_SUCCESS);
190 assert(tmpbuf_len == attestation_template_buffer_len);
191 assert(memcmp(attestation_template_buffer, tmpbuf, tmpbuf_len) == 0);
192
195 assert(yrc == YHR_SUCCESS);
196
197 uint16_t attested_key_id = 0; // ID 0 lets the device generate an ID
198 yrc = yh_util_generate_ec_key(session, &attested_key_id, key_label,
199 domain_five, &capabilities, YH_ALGO_EC_P256);
200 assert(yrc == YHR_SUCCESS);
201
202 printf("Generated attested key with ID %04x\n", attested_key_id);
203
204 uint8_t attestation[2048];
205 size_t attestation_len = sizeof(attestation);
206
208 attesting_key_id, attestation,
209 &attestation_len);
210 assert(yrc == YHR_SUCCESS);
211
212 const unsigned char *ptr = attestation;
213
214 X509 *x509 = d2i_X509(NULL, &ptr, attestation_len);
215 assert(x509 != NULL);
216
217 BIO *STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
218
219 X509_print_ex(STDout, x509, 0, 0);
220
221 BIO_free(STDout);
222
223 const STACK_OF(X509_EXTENSION) *extensions_list = X509_get0_extensions(x509);
224 assert(sk_X509_EXTENSION_num(extensions_list) >= 6);
225
226 for (int i = 0; i < sk_X509_EXTENSION_num(extensions_list); i++) {
227 X509_EXTENSION *extension;
228
229 extension = sk_X509_EXTENSION_value(extensions_list, i);
230
231 print_extension(extension);
232 }
233
234 X509_free(x509);
235
237 assert(yrc == YHR_SUCCESS);
238
240 assert(yrc == YHR_SUCCESS);
241
242 yrc = yh_disconnect(connector);
243 assert(yrc == YHR_SUCCESS);
244
245 yrc = yh_exit();
246 assert(yrc == YHR_SUCCESS);
247
248 return 0;
249}
#define DEFAULT_CONNECTOR_URL
Definition attest.c:34
int main(void)
Definition attest.c:107
const char * key_label
Definition attest.c:38
const char attestation_template_file[]
Definition attest.c:37
CK_SESSION_HANDLE session
ASN1_OCTET_STRING * X509_EXTENSION_get_data(X509_EXTENSION *ex)
ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex)
const STACK_OF(X509_EXTENSION)
#define value
Definition pkcs11.h:157
#define value_len
Definition pkcs11.h:158
unsigned short uint16_t
Definition stdint.h:125
unsigned char uint8_t
Definition stdint.h:124
Capabilities representation.
Definition yubihsm.h:162
uint8_t capabilities[YH_CAPABILITIES_LEN]
Capabilities is represented as an 8 byte uint8_t array.
Definition yubihsm.h:164
yh_rc yh_util_import_opaque(yh_session *session, uint16_t *object_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const uint8_t *in, size_t in_len)
Definition yubihsm.c:2666
yh_rc yh_destroy_session(yh_session **session)
Definition yubihsm.c:890
yh_rc yh_util_generate_ec_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm)
Definition yubihsm.c:1913
yh_rc yh_exit(void)
Definition yubihsm.c:3910
yh_rc yh_create_session_derived(yh_connector *connector, uint16_t authkey_id, const uint8_t *password, size_t password_len, bool recreate, yh_session **session)
Definition yubihsm.c:593
yh_rc yh_init(void)
Definition yubihsm.c:3857
yh_rc yh_util_get_opaque(yh_session *session, uint16_t object_id, uint8_t *out, size_t *out_len)
Definition yubihsm.c:2636
yh_rc yh_util_sign_attestation_certificate(yh_session *session, uint16_t key_id, uint16_t attest_id, uint8_t *out, size_t *out_len)
Definition yubihsm.c:3495
yh_rc yh_util_close_session(yh_session *session)
Definition yubihsm.c:1257
yh_rc yh_authenticate_session(yh_session *session)
Definition yubihsm.c:2927
yh_rc yh_string_to_domains(const char *domains, uint16_t *result)
Definition yubihsm.c:4535
yh_rc yh_init_connector(const char *url, yh_connector **connector)
Definition yubihsm.c:4024
yh_rc yh_connect(yh_connector *connector, int timeout)
Definition yubihsm.c:4079
yh_rc yh_string_to_capabilities(const char *capability, yh_capabilities *result)
Definition yubihsm.c:4115
yh_rc yh_disconnect(yh_connector *connector)
Definition yubihsm.c:4097
yh_rc yh_get_session_id(yh_session *session, uint8_t *sid)
Definition yubihsm.c:2915
@ YH_ALGO_OPAQUE_X509_CERTIFICATE
opaque-x509-certificate
Definition yubihsm.h:452
@ YH_ALGO_EC_P256
ecp256
Definition yubihsm.h:414
#define YH_CAPABILITIES_LEN
Length of capabilities array.
Definition yubihsm.h:119
yh_rc
Definition yubihsm.h:170
@ YHR_GENERIC_ERROR
Return value when encountering an unknown error.
Definition yubihsm.h:228
@ YHR_SUCCESS
Returned value when function was successful.
Definition yubihsm.h:172
yh_capabilities capabilities
uint32_t serial
char * label
uint16_t domains
yh_object_descriptor object
yh_rc yrc
memset(pInfo->slotDescription, ' ', 64)