summaryrefslogtreecommitdiffstats
path: root/src/fido/types.h
blob: 01d68200c19c09c4a953d1e47b2ba882f4710b3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/*
 * Copyright (c) 2018-2022 Yubico AB. All rights reserved.
 * SPDX-License-Identifier: BSD-2-Clause
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _FIDO_TYPES_H
#define _FIDO_TYPES_H

#ifdef __MINGW32__
#include <sys/types.h>
#endif

#include <signal.h>
#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

struct fido_dev;

typedef void *fido_dev_io_open_t(const char *);
typedef void  fido_dev_io_close_t(void *);
typedef int   fido_dev_io_read_t(void *, unsigned char *, size_t, int);
typedef int   fido_dev_io_write_t(void *, const unsigned char *, size_t);
typedef int   fido_dev_rx_t(struct fido_dev *, uint8_t, unsigned char *, size_t, int);
typedef int   fido_dev_tx_t(struct fido_dev *, uint8_t, const unsigned char *, size_t);

typedef struct fido_dev_io {
	fido_dev_io_open_t  *open;
	fido_dev_io_close_t *close;
	fido_dev_io_read_t  *read;
	fido_dev_io_write_t *write;
} fido_dev_io_t;

typedef struct fido_dev_transport {
	fido_dev_rx_t *rx;
	fido_dev_tx_t *tx;
} fido_dev_transport_t;

typedef enum {
	FIDO_OPT_OMIT = 0, /* use authenticator's default */
	FIDO_OPT_FALSE,    /* explicitly set option to false */
	FIDO_OPT_TRUE,     /* explicitly set option to true */
} fido_opt_t;

typedef void fido_log_handler_t(const char *);

#undef  _FIDO_SIGSET_DEFINED
#define _FIDO_SIGSET_DEFINED
#ifdef _WIN32
typedef int fido_sigset_t;
#elif defined(SIG_BLOCK)
typedef sigset_t fido_sigset_t;
#else
#undef _FIDO_SIGSET_DEFINED
#endif

#ifdef _FIDO_INTERNAL
#include "packed.h"
#include "blob.h"

/* COSE ES256 (ECDSA over P-256 with SHA-256) public key */
typedef struct es256_pk {
	unsigned char	x[32];
	unsigned char	y[32];
} es256_pk_t;

/* COSE ES256 (ECDSA over P-256 with SHA-256) (secret) key */
typedef struct es256_sk {
	unsigned char	d[32];
} es256_sk_t;

/* COSE ES384 (ECDSA over P-384 with SHA-384) public key */
typedef struct es384_pk {
	unsigned char	x[48];
	unsigned char	y[48];
} es384_pk_t;

/* COSE RS256 (2048-bit RSA with PKCS1 padding and SHA-256) public key */
typedef struct rs256_pk {
	unsigned char n[256];
	unsigned char e[3];
} rs256_pk_t;

/* COSE EDDSA (ED25519) */
typedef struct eddsa_pk {
	unsigned char x[32];
} eddsa_pk_t;

PACKED_TYPE(fido_authdata_t,
struct fido_authdata {
	unsigned char rp_id_hash[32]; /* sha256 of fido_rp.id */
	uint8_t       flags;          /* user present/verified */
	uint32_t      sigcount;       /* signature counter */
	/* actually longer */
})

PACKED_TYPE(fido_attcred_raw_t,
struct fido_attcred_raw {
	unsigned char aaguid[16]; /* credential's aaguid */
	uint16_t      id_len;     /* credential id length */
	uint8_t       body[];     /* credential id + pubkey */
})

typedef struct fido_attcred {
	unsigned char aaguid[16]; /* credential's aaguid */
	fido_blob_t   id;         /* credential id */
	int           type;       /* credential's cose algorithm */
	union {                   /* credential's public key */
		es256_pk_t es256;
		es384_pk_t es384;
		rs256_pk_t rs256;
		eddsa_pk_t eddsa;
	} pubkey;
} fido_attcred_t;

typedef struct fido_attstmt {
	fido_blob_t certinfo; /* tpm attestation TPMS_ATTEST structure */
	fido_blob_t pubarea;  /* tpm attestation TPMT_PUBLIC structure */
	fido_blob_t cbor;     /* cbor-encoded attestation statement */
	fido_blob_t x5c;      /* attestation certificate */
	fido_blob_t sig;      /* attestation signature */
	int         alg;      /* attestation algorithm (cose) */
} fido_attstmt_t;

typedef struct fido_rp {
	char *id;   /* relying party id */
	char *name; /* relying party name */
} fido_rp_t;

typedef struct fido_user {
	fido_blob_t  id;           /* required */
	char        *icon;         /* optional */
	char        *name;         /* optional */
	char        *display_name; /* required */
} fido_user_t;

typedef struct fido_cred_ext {
	int    mask;      /* enabled extensions */
	int    prot;      /* protection policy */
	size_t minpinlen; /* minimum pin length */
} fido_cred_ext_t;

typedef struct fido_cred {
	fido_blob_t       cd;            /* client data */
	fido_blob_t       cdh;           /* client data hash */
	fido_rp_t         rp;            /* relying party */
	fido_user_t       user;          /* user entity */
	fido_blob_array_t excl;          /* list of credential ids to exclude */
	fido_opt_t        rk;            /* resident key */
	fido_opt_t        uv;            /* user verification */
	fido_cred_ext_t   ext;           /* extensions */
	int               type;          /* cose algorithm */
	char             *fmt;           /* credential format */
	fido_cred_ext_t   authdata_ext;  /* decoded extensions */
	fido_blob_t       authdata_cbor; /* cbor-encoded payload */
	fido_blob_t       authdata_raw;  /* cbor-decoded payload */
	fido_authdata_t   authdata;      /* decoded authdata payload */
	fido_attcred_t    attcred;       /* returned credential (key + id) */
	fido_attstmt_t    attstmt;       /* attestation statement (x509 + sig) */
	fido_blob_t       largeblob_key; /* decoded large blob key */
	fido_blob_t       blob;          /* CTAP 2.1 credBlob */
} fido_cred_t;

typedef struct fido_assert_extattr {
	int         mask;            /* decoded extensions */
	fido_blob_t hmac_secret_enc; /* hmac secret, encrypted */
	fido_blob_t blob;            /* decoded CTAP 2.1 credBlob */
} fido_assert_extattr_t;

typedef struct _fido_assert_stmt {
	fido_blob_t           id;            /* credential id */
	fido_user_t           user;          /* user attributes */
	fido_blob_t           hmac_secret;   /* hmac secret */
	fido_assert_extattr_t authdata_ext;  /* decoded extensions */
	fido_blob_t           authdata_cbor; /* raw cbor payload */
	fido_blob_t           authdata_raw;  /* raw authdata */
	fido_authdata_t       authdata;      /* decoded authdata payload */
	fido_blob_t           sig;           /* signature of cdh + authdata */
	fido_blob_t           largeblob_key; /* decoded large blob key */
} fido_assert_stmt;

typedef struct fido_assert_ext {
	int         mask;                /* enabled extensions */
	fido_blob_t hmac_salt;           /* optional hmac-secret salt */
} fido_assert_ext_t;

typedef struct fido_assert {
	char              *rp_id;        /* relying party id */
	char              *appid;        /* winhello u2f appid */
	fido_blob_t        cd;           /* client data */
	fido_blob_t        cdh;          /* client data hash */
	fido_blob_array_t  allow_list;   /* list of allowed credentials */
	fido_opt_t         up;           /* user presence */
	fido_opt_t         uv;           /* user verification */
	fido_assert_ext_t  ext;          /* enabled extensions */
	fido_assert_stmt  *stmt;         /* array of expected assertions */
	size_t             stmt_cnt;     /* number of allocated assertions */
	size_t             stmt_len;     /* number of received assertions */
} fido_assert_t;

typedef struct fido_opt_array {
	char **name;
	bool *value;
	size_t len;
} fido_opt_array_t;

typedef struct fido_str_array {
	char **ptr;
	size_t len;
} fido_str_array_t;

typedef struct fido_byte_array {
	uint8_t *ptr;
	size_t len;
} fido_byte_array_t;

typedef struct fido_algo {
	char *type;
	int cose;
} fido_algo_t;

typedef struct fido_algo_array {
	fido_algo_t *ptr;
	size_t len;
} fido_algo_array_t;

typedef struct fido_cert_array {
	char **name;
	uint64_t *value;
	size_t len;
} fido_cert_array_t;

typedef struct fido_cbor_info {
	fido_str_array_t  versions;       /* supported versions: fido2|u2f */
	fido_str_array_t  extensions;     /* list of supported extensions */
	fido_str_array_t  transports;     /* list of supported transports */
	unsigned char     aaguid[16];     /* aaguid */
	fido_opt_array_t  options;        /* list of supported options */
	uint64_t          maxmsgsiz;      /* maximum message size */
	fido_byte_array_t protocols;      /* supported pin protocols */
	fido_algo_array_t algorithms;     /* list of supported algorithms */
	uint64_t          maxcredcntlst;  /* max credentials in list */
	uint64_t          maxcredidlen;   /* max credential ID length */
	uint64_t          fwversion;      /* firmware version */
	uint64_t          maxcredbloblen; /* max credBlob length */
	uint64_t          maxlargeblob;   /* max largeBlob array length */
	uint64_t          maxrpid_minlen; /* max rpid in set_pin_minlen_rpid */
	uint64_t          minpinlen;      /* min pin len enforced */
	uint64_t          uv_attempts;    /* platform uv attempts */
	uint64_t          uv_modality;    /* bitmask of supported uv types */
	int64_t           rk_remaining;   /* remaining resident credentials */
	bool              new_pin_reqd;   /* new pin required */
	fido_cert_array_t certs;          /* associated certifications */
} fido_cbor_info_t;

typedef struct fido_dev_info {
	char                 *path;         /* device path */
	int16_t               vendor_id;    /* 2-byte vendor id */
	int16_t               product_id;   /* 2-byte product id */
	char                 *manufacturer; /* manufacturer string */
	char                 *product;      /* product string */
	fido_dev_io_t         io;           /* i/o functions */
	fido_dev_transport_t  transport;    /* transport functions */
} fido_dev_info_t;

PACKED_TYPE(fido_ctap_info_t,
/* defined in section 8.1.9.1.3 (CTAPHID_INIT) of the fido2 ctap spec */
struct fido_ctap_info {
	uint64_t nonce;    /* echoed nonce */
	uint32_t cid;      /* channel id */
	uint8_t  protocol; /* ctaphid protocol id */
	uint8_t  major;    /* major version number */
	uint8_t  minor;    /* minor version number */
	uint8_t  build;    /* build version number */
	uint8_t  flags;    /* capabilities flags; see FIDO_CAP_* */
})

typedef struct fido_dev {
	uint64_t              nonce;      /* issued nonce */
	fido_ctap_info_t      attr;       /* device attributes */
	uint32_t              cid;        /* assigned channel id */
	char                 *path;       /* device path */
	void                 *io_handle;  /* abstract i/o handle */
	fido_dev_io_t         io;         /* i/o functions */
	bool                  io_own;     /* device has own io/transport */
	size_t                rx_len;     /* length of HID input reports */
	size_t                tx_len;     /* length of HID output reports */
	int                   flags;      /* internal flags; see FIDO_DEV_* */
	fido_dev_transport_t  transport;  /* transport functions */
	uint64_t	      maxmsgsize; /* max message size */
	int		      timeout_ms; /* read timeout in ms */
} fido_dev_t;

#else
typedef struct fido_assert fido_assert_t;
typedef struct fido_cbor_info fido_cbor_info_t;
typedef struct fido_cred fido_cred_t;
typedef struct fido_dev fido_dev_t;
typedef struct fido_dev_info fido_dev_info_t;
typedef struct es256_pk es256_pk_t;
typedef struct es256_sk es256_sk_t;
typedef struct es384_pk es384_pk_t;
typedef struct rs256_pk rs256_pk_t;
typedef struct eddsa_pk eddsa_pk_t;
#endif /* _FIDO_INTERNAL */

#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */

#endif /* !_FIDO_TYPES_H */