1/*
2 * Copyright (c) 2018-2022 Yubico AB. All rights reserved.
3 * Use of this source code is governed by a BSD-style
4 * license that can be found in the LICENSE file.
5 */
6
7#ifndef _FIDO_TYPES_H
8#define _FIDO_TYPES_H
9
10#ifdef __MINGW32__
11#include <sys/types.h>
12#endif
13
14#include <signal.h>
15#include <stddef.h>
16#include <stdint.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif /* __cplusplus */
21
22struct fido_dev;
23
24typedef void *fido_dev_io_open_t(const char *);
25typedef void  fido_dev_io_close_t(void *);
26typedef int   fido_dev_io_read_t(void *, unsigned char *, size_t, int);
27typedef int   fido_dev_io_write_t(void *, const unsigned char *, size_t);
28typedef int   fido_dev_rx_t(struct fido_dev *, uint8_t, unsigned char *, size_t, int);
29typedef int   fido_dev_tx_t(struct fido_dev *, uint8_t, const unsigned char *, size_t);
30
31typedef struct fido_dev_io {
32	fido_dev_io_open_t  *open;
33	fido_dev_io_close_t *close;
34	fido_dev_io_read_t  *read;
35	fido_dev_io_write_t *write;
36} fido_dev_io_t;
37
38typedef struct fido_dev_transport {
39	fido_dev_rx_t *rx;
40	fido_dev_tx_t *tx;
41} fido_dev_transport_t;
42
43typedef enum {
44	FIDO_OPT_OMIT = 0, /* use authenticator's default */
45	FIDO_OPT_FALSE,    /* explicitly set option to false */
46	FIDO_OPT_TRUE,     /* explicitly set option to true */
47} fido_opt_t;
48
49typedef void fido_log_handler_t(const char *);
50
51#undef  _FIDO_SIGSET_DEFINED
52#define _FIDO_SIGSET_DEFINED
53#ifdef _WIN32
54typedef int fido_sigset_t;
55#elif defined(SIG_BLOCK)
56typedef sigset_t fido_sigset_t;
57#else
58#undef _FIDO_SIGSET_DEFINED
59#endif
60
61#ifdef _FIDO_INTERNAL
62#include "packed.h"
63#include "blob.h"
64
65/* COSE ES256 (ECDSA over P-256 with SHA-256) public key */
66typedef struct es256_pk {
67	unsigned char	x[32];
68	unsigned char	y[32];
69} es256_pk_t;
70
71/* COSE ES256 (ECDSA over P-256 with SHA-256) (secret) key */
72typedef struct es256_sk {
73	unsigned char	d[32];
74} es256_sk_t;
75
76/* COSE RS256 (2048-bit RSA with PKCS1 padding and SHA-256) public key */
77typedef struct rs256_pk {
78	unsigned char n[256];
79	unsigned char e[3];
80} rs256_pk_t;
81
82/* COSE EDDSA (ED25519) */
83typedef struct eddsa_pk {
84	unsigned char x[32];
85} eddsa_pk_t;
86
87PACKED_TYPE(fido_authdata_t,
88struct fido_authdata {
89	unsigned char rp_id_hash[32]; /* sha256 of fido_rp.id */
90	uint8_t       flags;          /* user present/verified */
91	uint32_t      sigcount;       /* signature counter */
92	/* actually longer */
93})
94
95PACKED_TYPE(fido_attcred_raw_t,
96struct fido_attcred_raw {
97	unsigned char aaguid[16]; /* credential's aaguid */
98	uint16_t      id_len;     /* credential id length */
99	uint8_t       body[];     /* credential id + pubkey */
100})
101
102typedef struct fido_attcred {
103	unsigned char aaguid[16]; /* credential's aaguid */
104	fido_blob_t   id;         /* credential id */
105	int           type;       /* credential's cose algorithm */
106	union {                   /* credential's public key */
107		es256_pk_t es256;
108		rs256_pk_t rs256;
109		eddsa_pk_t eddsa;
110	} pubkey;
111} fido_attcred_t;
112
113typedef struct fido_attstmt {
114	fido_blob_t certinfo; /* tpm attestation TPMS_ATTEST structure */
115	fido_blob_t pubarea;  /* tpm attestation TPMT_PUBLIC structure */
116	fido_blob_t cbor;     /* cbor-encoded attestation statement */
117	fido_blob_t x5c;      /* attestation certificate */
118	fido_blob_t sig;      /* attestation signature */
119	int         alg;      /* attestation algorithm (cose) */
120} fido_attstmt_t;
121
122typedef struct fido_rp {
123	char *id;   /* relying party id */
124	char *name; /* relying party name */
125} fido_rp_t;
126
127typedef struct fido_user {
128	fido_blob_t  id;           /* required */
129	char        *icon;         /* optional */
130	char        *name;         /* optional */
131	char        *display_name; /* required */
132} fido_user_t;
133
134typedef struct fido_cred_ext {
135	int    mask;      /* enabled extensions */
136	int    prot;      /* protection policy */
137	size_t minpinlen; /* minimum pin length */
138} fido_cred_ext_t;
139
140typedef struct fido_cred {
141	fido_blob_t       cd;            /* client data */
142	fido_blob_t       cdh;           /* client data hash */
143	fido_rp_t         rp;            /* relying party */
144	fido_user_t       user;          /* user entity */
145	fido_blob_array_t excl;          /* list of credential ids to exclude */
146	fido_opt_t        rk;            /* resident key */
147	fido_opt_t        uv;            /* user verification */
148	fido_cred_ext_t   ext;           /* extensions */
149	int               type;          /* cose algorithm */
150	char             *fmt;           /* credential format */
151	fido_cred_ext_t   authdata_ext;  /* decoded extensions */
152	fido_blob_t       authdata_cbor; /* cbor-encoded payload */
153	fido_blob_t       authdata_raw;  /* cbor-decoded payload */
154	fido_authdata_t   authdata;      /* decoded authdata payload */
155	fido_attcred_t    attcred;       /* returned credential (key + id) */
156	fido_attstmt_t    attstmt;       /* attestation statement (x509 + sig) */
157	fido_blob_t       largeblob_key; /* decoded large blob key */
158	fido_blob_t       blob;          /* CTAP 2.1 credBlob */
159} fido_cred_t;
160
161typedef struct fido_assert_extattr {
162	int         mask;            /* decoded extensions */
163	fido_blob_t hmac_secret_enc; /* hmac secret, encrypted */
164	fido_blob_t blob;            /* decoded CTAP 2.1 credBlob */
165} fido_assert_extattr_t;
166
167typedef struct _fido_assert_stmt {
168	fido_blob_t           id;            /* credential id */
169	fido_user_t           user;          /* user attributes */
170	fido_blob_t           hmac_secret;   /* hmac secret */
171	fido_assert_extattr_t authdata_ext;  /* decoded extensions */
172	fido_blob_t           authdata_cbor; /* raw cbor payload */
173	fido_authdata_t       authdata;      /* decoded authdata payload */
174	fido_blob_t           sig;           /* signature of cdh + authdata */
175	fido_blob_t           largeblob_key; /* decoded large blob key */
176} fido_assert_stmt;
177
178typedef struct fido_assert_ext {
179	int         mask;                /* enabled extensions */
180	fido_blob_t hmac_salt;           /* optional hmac-secret salt */
181} fido_assert_ext_t;
182
183typedef struct fido_assert {
184	char              *rp_id;        /* relying party id */
185	fido_blob_t        cd;           /* client data */
186	fido_blob_t        cdh;          /* client data hash */
187	fido_blob_array_t  allow_list;   /* list of allowed credentials */
188	fido_opt_t         up;           /* user presence */
189	fido_opt_t         uv;           /* user verification */
190	fido_assert_ext_t  ext;          /* enabled extensions */
191	fido_assert_stmt  *stmt;         /* array of expected assertions */
192	size_t             stmt_cnt;     /* number of allocated assertions */
193	size_t             stmt_len;     /* number of received assertions */
194} fido_assert_t;
195
196typedef struct fido_opt_array {
197	char **name;
198	bool *value;
199	size_t len;
200} fido_opt_array_t;
201
202typedef struct fido_str_array {
203	char **ptr;
204	size_t len;
205} fido_str_array_t;
206
207typedef struct fido_byte_array {
208	uint8_t *ptr;
209	size_t len;
210} fido_byte_array_t;
211
212typedef struct fido_algo {
213	char *type;
214	int cose;
215} fido_algo_t;
216
217typedef struct fido_algo_array {
218	fido_algo_t *ptr;
219	size_t len;
220} fido_algo_array_t;
221
222typedef struct fido_cbor_info {
223	fido_str_array_t  versions;       /* supported versions: fido2|u2f */
224	fido_str_array_t  extensions;     /* list of supported extensions */
225	fido_str_array_t  transports;     /* list of supported transports */
226	unsigned char     aaguid[16];     /* aaguid */
227	fido_opt_array_t  options;        /* list of supported options */
228	uint64_t          maxmsgsiz;      /* maximum message size */
229	fido_byte_array_t protocols;      /* supported pin protocols */
230	fido_algo_array_t algorithms;     /* list of supported algorithms */
231	uint64_t          maxcredcntlst;  /* max credentials in list */
232	uint64_t          maxcredidlen;   /* max credential ID length */
233	uint64_t          fwversion;      /* firmware version */
234	uint64_t          maxcredbloblen; /* max credBlob length */
235	uint64_t          maxlargeblob;   /* max largeBlob array length */
236} fido_cbor_info_t;
237
238typedef struct fido_dev_info {
239	char                 *path;         /* device path */
240	int16_t               vendor_id;    /* 2-byte vendor id */
241	int16_t               product_id;   /* 2-byte product id */
242	char                 *manufacturer; /* manufacturer string */
243	char                 *product;      /* product string */
244	fido_dev_io_t         io;           /* i/o functions */
245	fido_dev_transport_t  transport;    /* transport functions */
246} fido_dev_info_t;
247
248PACKED_TYPE(fido_ctap_info_t,
249/* defined in section 8.1.9.1.3 (CTAPHID_INIT) of the fido2 ctap spec */
250struct fido_ctap_info {
251	uint64_t nonce;    /* echoed nonce */
252	uint32_t cid;      /* channel id */
253	uint8_t  protocol; /* ctaphid protocol id */
254	uint8_t  major;    /* major version number */
255	uint8_t  minor;    /* minor version number */
256	uint8_t  build;    /* build version number */
257	uint8_t  flags;    /* capabilities flags; see FIDO_CAP_* */
258})
259
260typedef struct fido_dev {
261	uint64_t              nonce;      /* issued nonce */
262	fido_ctap_info_t      attr;       /* device attributes */
263	uint32_t              cid;        /* assigned channel id */
264	char                 *path;       /* device path */
265	void                 *io_handle;  /* abstract i/o handle */
266	fido_dev_io_t         io;         /* i/o functions */
267	bool                  io_own;     /* device has own io/transport */
268	size_t                rx_len;     /* length of HID input reports */
269	size_t                tx_len;     /* length of HID output reports */
270	int                   flags;      /* internal flags; see FIDO_DEV_* */
271	fido_dev_transport_t  transport;  /* transport functions */
272	uint64_t	      maxmsgsize; /* max message size */
273	int		      timeout_ms; /* read timeout in ms */
274} fido_dev_t;
275
276#else
277typedef struct fido_assert fido_assert_t;
278typedef struct fido_cbor_info fido_cbor_info_t;
279typedef struct fido_cred fido_cred_t;
280typedef struct fido_dev fido_dev_t;
281typedef struct fido_dev_info fido_dev_info_t;
282typedef struct es256_pk es256_pk_t;
283typedef struct es256_sk es256_sk_t;
284typedef struct rs256_pk rs256_pk_t;
285typedef struct eddsa_pk eddsa_pk_t;
286#endif /* _FIDO_INTERNAL */
287
288#ifdef __cplusplus
289} /* extern "C" */
290#endif /* __cplusplus */
291
292#endif /* !_FIDO_TYPES_H */
293