1/*
2 * Copyright (c) 2018-2022 Yubico AB. All rights reserved.
3 * SPDX-License-Identifier: BSD-2-Clause
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 *    1. Redistributions of source code must retain the above copyright
10 *       notice, this list of conditions and the following disclaimer.
11 *    2. Redistributions in binary form must reproduce the above copyright
12 *       notice, this list of conditions and the following disclaimer in
13 *       the documentation and/or other materials provided with the
14 *       distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef _FIDO_TYPES_H
30#define _FIDO_TYPES_H
31
32#ifdef __MINGW32__
33#include <sys/types.h>
34#endif
35
36#include <signal.h>
37#include <stddef.h>
38#include <stdint.h>
39
40#ifdef __cplusplus
41extern "C" {
42#endif /* __cplusplus */
43
44struct fido_dev;
45
46typedef void *fido_dev_io_open_t(const char *);
47typedef void  fido_dev_io_close_t(void *);
48typedef int   fido_dev_io_read_t(void *, unsigned char *, size_t, int);
49typedef int   fido_dev_io_write_t(void *, const unsigned char *, size_t);
50typedef int   fido_dev_rx_t(struct fido_dev *, uint8_t, unsigned char *, size_t, int);
51typedef int   fido_dev_tx_t(struct fido_dev *, uint8_t, const unsigned char *, size_t);
52
53typedef struct fido_dev_io {
54	fido_dev_io_open_t  *open;
55	fido_dev_io_close_t *close;
56	fido_dev_io_read_t  *read;
57	fido_dev_io_write_t *write;
58} fido_dev_io_t;
59
60typedef struct fido_dev_transport {
61	fido_dev_rx_t *rx;
62	fido_dev_tx_t *tx;
63} fido_dev_transport_t;
64
65typedef enum {
66	FIDO_OPT_OMIT = 0, /* use authenticator's default */
67	FIDO_OPT_FALSE,    /* explicitly set option to false */
68	FIDO_OPT_TRUE,     /* explicitly set option to true */
69} fido_opt_t;
70
71typedef void fido_log_handler_t(const char *);
72
73#undef  _FIDO_SIGSET_DEFINED
74#define _FIDO_SIGSET_DEFINED
75#ifdef _WIN32
76typedef int fido_sigset_t;
77#elif defined(SIG_BLOCK)
78typedef sigset_t fido_sigset_t;
79#else
80#undef _FIDO_SIGSET_DEFINED
81#endif
82
83#ifdef _FIDO_INTERNAL
84#include "packed.h"
85#include "blob.h"
86
87/* COSE ES256 (ECDSA over P-256 with SHA-256) public key */
88typedef struct es256_pk {
89	unsigned char	x[32];
90	unsigned char	y[32];
91} es256_pk_t;
92
93/* COSE ES256 (ECDSA over P-256 with SHA-256) (secret) key */
94typedef struct es256_sk {
95	unsigned char	d[32];
96} es256_sk_t;
97
98/* COSE ES384 (ECDSA over P-384 with SHA-384) public key */
99typedef struct es384_pk {
100	unsigned char	x[48];
101	unsigned char	y[48];
102} es384_pk_t;
103
104/* COSE RS256 (2048-bit RSA with PKCS1 padding and SHA-256) public key */
105typedef struct rs256_pk {
106	unsigned char n[256];
107	unsigned char e[3];
108} rs256_pk_t;
109
110/* COSE EDDSA (ED25519) */
111typedef struct eddsa_pk {
112	unsigned char x[32];
113} eddsa_pk_t;
114
115PACKED_TYPE(fido_authdata_t,
116struct fido_authdata {
117	unsigned char rp_id_hash[32]; /* sha256 of fido_rp.id */
118	uint8_t       flags;          /* user present/verified */
119	uint32_t      sigcount;       /* signature counter */
120	/* actually longer */
121})
122
123PACKED_TYPE(fido_attcred_raw_t,
124struct fido_attcred_raw {
125	unsigned char aaguid[16]; /* credential's aaguid */
126	uint16_t      id_len;     /* credential id length */
127	uint8_t       body[];     /* credential id + pubkey */
128})
129
130typedef struct fido_attcred {
131	unsigned char aaguid[16]; /* credential's aaguid */
132	fido_blob_t   id;         /* credential id */
133	int           type;       /* credential's cose algorithm */
134	union {                   /* credential's public key */
135		es256_pk_t es256;
136		es384_pk_t es384;
137		rs256_pk_t rs256;
138		eddsa_pk_t eddsa;
139	} pubkey;
140} fido_attcred_t;
141
142typedef struct fido_attstmt {
143	fido_blob_t certinfo; /* tpm attestation TPMS_ATTEST structure */
144	fido_blob_t pubarea;  /* tpm attestation TPMT_PUBLIC structure */
145	fido_blob_t cbor;     /* cbor-encoded attestation statement */
146	fido_blob_t x5c;      /* attestation certificate */
147	fido_blob_t sig;      /* attestation signature */
148	int         alg;      /* attestation algorithm (cose) */
149} fido_attstmt_t;
150
151typedef struct fido_rp {
152	char *id;   /* relying party id */
153	char *name; /* relying party name */
154} fido_rp_t;
155
156typedef struct fido_user {
157	fido_blob_t  id;           /* required */
158	char        *icon;         /* optional */
159	char        *name;         /* optional */
160	char        *display_name; /* required */
161} fido_user_t;
162
163typedef struct fido_cred_ext {
164	int    mask;      /* enabled extensions */
165	int    prot;      /* protection policy */
166	size_t minpinlen; /* minimum pin length */
167} fido_cred_ext_t;
168
169typedef struct fido_cred {
170	fido_blob_t       cd;            /* client data */
171	fido_blob_t       cdh;           /* client data hash */
172	fido_rp_t         rp;            /* relying party */
173	fido_user_t       user;          /* user entity */
174	fido_blob_array_t excl;          /* list of credential ids to exclude */
175	fido_opt_t        rk;            /* resident key */
176	fido_opt_t        uv;            /* user verification */
177	fido_cred_ext_t   ext;           /* extensions */
178	int               type;          /* cose algorithm */
179	char             *fmt;           /* credential format */
180	fido_cred_ext_t   authdata_ext;  /* decoded extensions */
181	fido_blob_t       authdata_cbor; /* cbor-encoded payload */
182	fido_blob_t       authdata_raw;  /* cbor-decoded payload */
183	fido_authdata_t   authdata;      /* decoded authdata payload */
184	fido_attcred_t    attcred;       /* returned credential (key + id) */
185	fido_attstmt_t    attstmt;       /* attestation statement (x509 + sig) */
186	fido_blob_t       largeblob_key; /* decoded large blob key */
187	fido_blob_t       blob;          /* CTAP 2.1 credBlob */
188} fido_cred_t;
189
190typedef struct fido_assert_extattr {
191	int         mask;            /* decoded extensions */
192	fido_blob_t hmac_secret_enc; /* hmac secret, encrypted */
193	fido_blob_t blob;            /* decoded CTAP 2.1 credBlob */
194} fido_assert_extattr_t;
195
196typedef struct _fido_assert_stmt {
197	fido_blob_t           id;            /* credential id */
198	fido_user_t           user;          /* user attributes */
199	fido_blob_t           hmac_secret;   /* hmac secret */
200	fido_assert_extattr_t authdata_ext;  /* decoded extensions */
201	fido_blob_t           authdata_cbor; /* raw cbor payload */
202	fido_blob_t           authdata_raw;  /* raw authdata */
203	fido_authdata_t       authdata;      /* decoded authdata payload */
204	fido_blob_t           sig;           /* signature of cdh + authdata */
205	fido_blob_t           largeblob_key; /* decoded large blob key */
206} fido_assert_stmt;
207
208typedef struct fido_assert_ext {
209	int         mask;                /* enabled extensions */
210	fido_blob_t hmac_salt;           /* optional hmac-secret salt */
211} fido_assert_ext_t;
212
213typedef struct fido_assert {
214	char              *rp_id;        /* relying party id */
215	char              *appid;        /* winhello u2f appid */
216	fido_blob_t        cd;           /* client data */
217	fido_blob_t        cdh;          /* client data hash */
218	fido_blob_array_t  allow_list;   /* list of allowed credentials */
219	fido_opt_t         up;           /* user presence */
220	fido_opt_t         uv;           /* user verification */
221	fido_assert_ext_t  ext;          /* enabled extensions */
222	fido_assert_stmt  *stmt;         /* array of expected assertions */
223	size_t             stmt_cnt;     /* number of allocated assertions */
224	size_t             stmt_len;     /* number of received assertions */
225} fido_assert_t;
226
227typedef struct fido_opt_array {
228	char **name;
229	bool *value;
230	size_t len;
231} fido_opt_array_t;
232
233typedef struct fido_str_array {
234	char **ptr;
235	size_t len;
236} fido_str_array_t;
237
238typedef struct fido_byte_array {
239	uint8_t *ptr;
240	size_t len;
241} fido_byte_array_t;
242
243typedef struct fido_algo {
244	char *type;
245	int cose;
246} fido_algo_t;
247
248typedef struct fido_algo_array {
249	fido_algo_t *ptr;
250	size_t len;
251} fido_algo_array_t;
252
253typedef struct fido_cert_array {
254	char **name;
255	uint64_t *value;
256	size_t len;
257} fido_cert_array_t;
258
259typedef struct fido_cbor_info {
260	fido_str_array_t  versions;       /* supported versions: fido2|u2f */
261	fido_str_array_t  extensions;     /* list of supported extensions */
262	fido_str_array_t  transports;     /* list of supported transports */
263	unsigned char     aaguid[16];     /* aaguid */
264	fido_opt_array_t  options;        /* list of supported options */
265	uint64_t          maxmsgsiz;      /* maximum message size */
266	fido_byte_array_t protocols;      /* supported pin protocols */
267	fido_algo_array_t algorithms;     /* list of supported algorithms */
268	uint64_t          maxcredcntlst;  /* max credentials in list */
269	uint64_t          maxcredidlen;   /* max credential ID length */
270	uint64_t          fwversion;      /* firmware version */
271	uint64_t          maxcredbloblen; /* max credBlob length */
272	uint64_t          maxlargeblob;   /* max largeBlob array length */
273	uint64_t          maxrpid_minlen; /* max rpid in set_pin_minlen_rpid */
274	uint64_t          minpinlen;      /* min pin len enforced */
275	uint64_t          uv_attempts;    /* platform uv attempts */
276	uint64_t          uv_modality;    /* bitmask of supported uv types */
277	int64_t           rk_remaining;   /* remaining resident credentials */
278	bool              new_pin_reqd;   /* new pin required */
279	fido_cert_array_t certs;          /* associated certifications */
280} fido_cbor_info_t;
281
282typedef struct fido_dev_info {
283	char                 *path;         /* device path */
284	int16_t               vendor_id;    /* 2-byte vendor id */
285	int16_t               product_id;   /* 2-byte product id */
286	char                 *manufacturer; /* manufacturer string */
287	char                 *product;      /* product string */
288	fido_dev_io_t         io;           /* i/o functions */
289	fido_dev_transport_t  transport;    /* transport functions */
290} fido_dev_info_t;
291
292PACKED_TYPE(fido_ctap_info_t,
293/* defined in section 8.1.9.1.3 (CTAPHID_INIT) of the fido2 ctap spec */
294struct fido_ctap_info {
295	uint64_t nonce;    /* echoed nonce */
296	uint32_t cid;      /* channel id */
297	uint8_t  protocol; /* ctaphid protocol id */
298	uint8_t  major;    /* major version number */
299	uint8_t  minor;    /* minor version number */
300	uint8_t  build;    /* build version number */
301	uint8_t  flags;    /* capabilities flags; see FIDO_CAP_* */
302})
303
304typedef struct fido_dev {
305	uint64_t              nonce;      /* issued nonce */
306	fido_ctap_info_t      attr;       /* device attributes */
307	uint32_t              cid;        /* assigned channel id */
308	char                 *path;       /* device path */
309	void                 *io_handle;  /* abstract i/o handle */
310	fido_dev_io_t         io;         /* i/o functions */
311	bool                  io_own;     /* device has own io/transport */
312	size_t                rx_len;     /* length of HID input reports */
313	size_t                tx_len;     /* length of HID output reports */
314	int                   flags;      /* internal flags; see FIDO_DEV_* */
315	fido_dev_transport_t  transport;  /* transport functions */
316	uint64_t	      maxmsgsize; /* max message size */
317	int		      timeout_ms; /* read timeout in ms */
318} fido_dev_t;
319
320#else
321typedef struct fido_assert fido_assert_t;
322typedef struct fido_cbor_info fido_cbor_info_t;
323typedef struct fido_cred fido_cred_t;
324typedef struct fido_dev fido_dev_t;
325typedef struct fido_dev_info fido_dev_info_t;
326typedef struct es256_pk es256_pk_t;
327typedef struct es256_sk es256_sk_t;
328typedef struct es384_pk es384_pk_t;
329typedef struct rs256_pk rs256_pk_t;
330typedef struct eddsa_pk eddsa_pk_t;
331#endif /* _FIDO_INTERNAL */
332
333#ifdef __cplusplus
334} /* extern "C" */
335#endif /* __cplusplus */
336
337#endif /* !_FIDO_TYPES_H */
338