diff options
Diffstat (limited to 'src/fido')
-rw-r--r-- | src/fido/bio.h | 16 | ||||
-rw-r--r-- | src/fido/credman.h | 16 | ||||
-rw-r--r-- | src/fido/eddsa.h | 14 | ||||
-rw-r--r-- | src/fido/err.h | 8 | ||||
-rw-r--r-- | src/fido/es256.h | 14 | ||||
-rw-r--r-- | src/fido/param.h | 11 | ||||
-rw-r--r-- | src/fido/rs256.h | 14 | ||||
-rw-r--r-- | src/fido/types.h | 235 |
8 files changed, 328 insertions, 0 deletions
diff --git a/src/fido/bio.h b/src/fido/bio.h index 31dffe4..afe9ca4 100644 --- a/src/fido/bio.h +++ b/src/fido/bio.h | |||
@@ -10,8 +10,20 @@ | |||
10 | #include <stdint.h> | 10 | #include <stdint.h> |
11 | #include <stdlib.h> | 11 | #include <stdlib.h> |
12 | 12 | ||
13 | #ifdef _FIDO_INTERNAL | ||
14 | #include "blob.h" | ||
13 | #include "fido/err.h" | 15 | #include "fido/err.h" |
14 | #include "fido/param.h" | 16 | #include "fido/param.h" |
17 | #include "fido/types.h" | ||
18 | #else | ||
19 | #include <fido.h> | ||
20 | #include <fido/err.h> | ||
21 | #include <fido/param.h> | ||
22 | #endif | ||
23 | |||
24 | #ifdef __cplusplus | ||
25 | extern "C" { | ||
26 | #endif /* __cplusplus */ | ||
15 | 27 | ||
16 | #ifdef _FIDO_INTERNAL | 28 | #ifdef _FIDO_INTERNAL |
17 | struct fido_bio_template { | 29 | struct fido_bio_template { |
@@ -92,4 +104,8 @@ void fido_bio_info_free(fido_bio_info_t **); | |||
92 | void fido_bio_template_array_free(fido_bio_template_array_t **); | 104 | void fido_bio_template_array_free(fido_bio_template_array_t **); |
93 | void fido_bio_template_free(fido_bio_template_t **); | 105 | void fido_bio_template_free(fido_bio_template_t **); |
94 | 106 | ||
107 | #ifdef __cplusplus | ||
108 | } /* extern "C" */ | ||
109 | #endif /* __cplusplus */ | ||
110 | |||
95 | #endif /* !_FIDO_BIO_H */ | 111 | #endif /* !_FIDO_BIO_H */ |
diff --git a/src/fido/credman.h b/src/fido/credman.h index 1c7cafe..eaffd65 100644 --- a/src/fido/credman.h +++ b/src/fido/credman.h | |||
@@ -10,8 +10,20 @@ | |||
10 | #include <stdint.h> | 10 | #include <stdint.h> |
11 | #include <stdlib.h> | 11 | #include <stdlib.h> |
12 | 12 | ||
13 | #ifdef _FIDO_INTERNAL | ||
14 | #include "blob.h" | ||
13 | #include "fido/err.h" | 15 | #include "fido/err.h" |
14 | #include "fido/param.h" | 16 | #include "fido/param.h" |
17 | #include "fido/types.h" | ||
18 | #else | ||
19 | #include <fido.h> | ||
20 | #include <fido/err.h> | ||
21 | #include <fido/param.h> | ||
22 | #endif | ||
23 | |||
24 | #ifdef __cplusplus | ||
25 | extern "C" { | ||
26 | #endif /* __cplusplus */ | ||
15 | 27 | ||
16 | #ifdef _FIDO_INTERNAL | 28 | #ifdef _FIDO_INTERNAL |
17 | struct fido_credman_metadata { | 29 | struct fido_credman_metadata { |
@@ -71,4 +83,8 @@ void fido_credman_metadata_free(fido_credman_metadata_t **); | |||
71 | void fido_credman_rk_free(fido_credman_rk_t **); | 83 | void fido_credman_rk_free(fido_credman_rk_t **); |
72 | void fido_credman_rp_free(fido_credman_rp_t **); | 84 | void fido_credman_rp_free(fido_credman_rp_t **); |
73 | 85 | ||
86 | #ifdef __cplusplus | ||
87 | } /* extern "C" */ | ||
88 | #endif /* __cplusplus */ | ||
89 | |||
74 | #endif /* !_FIDO_CREDMAN_H */ | 90 | #endif /* !_FIDO_CREDMAN_H */ |
diff --git a/src/fido/eddsa.h b/src/fido/eddsa.h index 9de272d..4a81017 100644 --- a/src/fido/eddsa.h +++ b/src/fido/eddsa.h | |||
@@ -12,6 +12,16 @@ | |||
12 | #include <stdint.h> | 12 | #include <stdint.h> |
13 | #include <stdlib.h> | 13 | #include <stdlib.h> |
14 | 14 | ||
15 | #ifdef _FIDO_INTERNAL | ||
16 | #include "types.h" | ||
17 | #else | ||
18 | #include <fido.h> | ||
19 | #endif | ||
20 | |||
21 | #ifdef __cplusplus | ||
22 | extern "C" { | ||
23 | #endif /* __cplusplus */ | ||
24 | |||
15 | eddsa_pk_t *eddsa_pk_new(void); | 25 | eddsa_pk_t *eddsa_pk_new(void); |
16 | void eddsa_pk_free(eddsa_pk_t **); | 26 | void eddsa_pk_free(eddsa_pk_t **); |
17 | EVP_PKEY *eddsa_pk_to_EVP_PKEY(const eddsa_pk_t *); | 27 | EVP_PKEY *eddsa_pk_to_EVP_PKEY(const eddsa_pk_t *); |
@@ -37,4 +47,8 @@ void EVP_MD_CTX_free(EVP_MD_CTX *); | |||
37 | 47 | ||
38 | #endif /* _FIDO_INTERNAL */ | 48 | #endif /* _FIDO_INTERNAL */ |
39 | 49 | ||
50 | #ifdef __cplusplus | ||
51 | } /* extern "C" */ | ||
52 | #endif /* __cplusplus */ | ||
53 | |||
40 | #endif /* !_FIDO_EDDSA_H */ | 54 | #endif /* !_FIDO_EDDSA_H */ |
diff --git a/src/fido/err.h b/src/fido/err.h index 11f52bc..d7453fc 100644 --- a/src/fido/err.h +++ b/src/fido/err.h | |||
@@ -64,6 +64,14 @@ | |||
64 | #define FIDO_ERR_USER_PRESENCE_REQUIRED -8 | 64 | #define FIDO_ERR_USER_PRESENCE_REQUIRED -8 |
65 | #define FIDO_ERR_INTERNAL -9 | 65 | #define FIDO_ERR_INTERNAL -9 |
66 | 66 | ||
67 | #ifdef __cplusplus | ||
68 | extern "C" { | ||
69 | #endif /* __cplusplus */ | ||
70 | |||
67 | const char *fido_strerr(int); | 71 | const char *fido_strerr(int); |
68 | 72 | ||
73 | #ifdef __cplusplus | ||
74 | } /* extern "C" */ | ||
75 | #endif /* __cplusplus */ | ||
76 | |||
69 | #endif /* _FIDO_ERR_H */ | 77 | #endif /* _FIDO_ERR_H */ |
diff --git a/src/fido/es256.h b/src/fido/es256.h index d3d13dd..80f4db3 100644 --- a/src/fido/es256.h +++ b/src/fido/es256.h | |||
@@ -12,6 +12,16 @@ | |||
12 | #include <stdint.h> | 12 | #include <stdint.h> |
13 | #include <stdlib.h> | 13 | #include <stdlib.h> |
14 | 14 | ||
15 | #ifdef _FIDO_INTERNAL | ||
16 | #include "types.h" | ||
17 | #else | ||
18 | #include <fido.h> | ||
19 | #endif | ||
20 | |||
21 | #ifdef __cplusplus | ||
22 | extern "C" { | ||
23 | #endif /* __cplusplus */ | ||
24 | |||
15 | es256_pk_t *es256_pk_new(void); | 25 | es256_pk_t *es256_pk_new(void); |
16 | void es256_pk_free(es256_pk_t **); | 26 | void es256_pk_free(es256_pk_t **); |
17 | EVP_PKEY *es256_pk_to_EVP_PKEY(const es256_pk_t *); | 27 | EVP_PKEY *es256_pk_to_EVP_PKEY(const es256_pk_t *); |
@@ -31,4 +41,8 @@ int es256_pk_set_x(es256_pk_t *, const unsigned char *); | |||
31 | int es256_pk_set_y(es256_pk_t *, const unsigned char *); | 41 | int es256_pk_set_y(es256_pk_t *, const unsigned char *); |
32 | #endif | 42 | #endif |
33 | 43 | ||
44 | #ifdef __cplusplus | ||
45 | } /* extern "C" */ | ||
46 | #endif /* __cplusplus */ | ||
47 | |||
34 | #endif /* !_FIDO_ES256_H */ | 48 | #endif /* !_FIDO_ES256_H */ |
diff --git a/src/fido/param.h b/src/fido/param.h index 9e12ac6..7d3c0cc 100644 --- a/src/fido/param.h +++ b/src/fido/param.h | |||
@@ -58,6 +58,11 @@ | |||
58 | #define FIDO_RANDOM_DEV "/dev/urandom" | 58 | #define FIDO_RANDOM_DEV "/dev/urandom" |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | /* Maximum message size in bytes. */ | ||
62 | #ifndef FIDO_MAXMSG | ||
63 | #define FIDO_MAXMSG 1200 | ||
64 | #endif | ||
65 | |||
61 | /* CTAP capability bits. */ | 66 | /* CTAP capability bits. */ |
62 | #define FIDO_CAP_WINK 0x01 /* if set, device supports CTAP_CMD_WINK */ | 67 | #define FIDO_CAP_WINK 0x01 /* if set, device supports CTAP_CMD_WINK */ |
63 | #define FIDO_CAP_CBOR 0x04 /* if set, device supports CTAP_CMD_CBOR */ | 68 | #define FIDO_CAP_CBOR 0x04 /* if set, device supports CTAP_CMD_CBOR */ |
@@ -80,5 +85,11 @@ | |||
80 | 85 | ||
81 | /* Supported extensions. */ | 86 | /* Supported extensions. */ |
82 | #define FIDO_EXT_HMAC_SECRET 0x01 | 87 | #define FIDO_EXT_HMAC_SECRET 0x01 |
88 | #define FIDO_EXT_CRED_PROTECT 0x02 | ||
89 | |||
90 | /* Supported credential protection policies. */ | ||
91 | #define FIDO_CRED_PROT_UV_OPTIONAL 0x01 | ||
92 | #define FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID 0x02 | ||
93 | #define FIDO_CRED_PROT_UV_REQUIRED 0x03 | ||
83 | 94 | ||
84 | #endif /* !_FIDO_PARAM_H */ | 95 | #endif /* !_FIDO_PARAM_H */ |
diff --git a/src/fido/rs256.h b/src/fido/rs256.h index d2fa162..2b08d59 100644 --- a/src/fido/rs256.h +++ b/src/fido/rs256.h | |||
@@ -12,6 +12,16 @@ | |||
12 | #include <stdint.h> | 12 | #include <stdint.h> |
13 | #include <stdlib.h> | 13 | #include <stdlib.h> |
14 | 14 | ||
15 | #ifdef _FIDO_INTERNAL | ||
16 | #include "types.h" | ||
17 | #else | ||
18 | #include <fido.h> | ||
19 | #endif | ||
20 | |||
21 | #ifdef __cplusplus | ||
22 | extern "C" { | ||
23 | #endif /* __cplusplus */ | ||
24 | |||
15 | rs256_pk_t *rs256_pk_new(void); | 25 | rs256_pk_t *rs256_pk_new(void); |
16 | void rs256_pk_free(rs256_pk_t **); | 26 | void rs256_pk_free(rs256_pk_t **); |
17 | EVP_PKEY *rs256_pk_to_EVP_PKEY(const rs256_pk_t *); | 27 | EVP_PKEY *rs256_pk_to_EVP_PKEY(const rs256_pk_t *); |
@@ -19,4 +29,8 @@ EVP_PKEY *rs256_pk_to_EVP_PKEY(const rs256_pk_t *); | |||
19 | int rs256_pk_from_RSA(rs256_pk_t *, const RSA *); | 29 | int rs256_pk_from_RSA(rs256_pk_t *, const RSA *); |
20 | int rs256_pk_from_ptr(rs256_pk_t *, const void *, size_t); | 30 | int rs256_pk_from_ptr(rs256_pk_t *, const void *, size_t); |
21 | 31 | ||
32 | #ifdef __cplusplus | ||
33 | } /* extern "C" */ | ||
34 | #endif /* __cplusplus */ | ||
35 | |||
22 | #endif /* !_FIDO_RS256_H */ | 36 | #endif /* !_FIDO_RS256_H */ |
diff --git a/src/fido/types.h b/src/fido/types.h new file mode 100644 index 0000000..5df5e36 --- /dev/null +++ b/src/fido/types.h | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2018 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 | #include <stddef.h> | ||
11 | #include <stdint.h> | ||
12 | |||
13 | #ifdef __cplusplus | ||
14 | extern "C" { | ||
15 | #endif /* __cplusplus */ | ||
16 | |||
17 | struct fido_dev; | ||
18 | |||
19 | typedef void *fido_dev_io_open_t(const char *); | ||
20 | typedef void fido_dev_io_close_t(void *); | ||
21 | typedef int fido_dev_io_read_t(void *, unsigned char *, size_t, int); | ||
22 | typedef int fido_dev_io_write_t(void *, const unsigned char *, size_t); | ||
23 | typedef int fido_dev_rx_t(struct fido_dev *, uint8_t, unsigned char *, size_t, int); | ||
24 | typedef int fido_dev_tx_t(struct fido_dev *, uint8_t, const unsigned char *, size_t); | ||
25 | |||
26 | typedef struct fido_dev_io { | ||
27 | fido_dev_io_open_t *open; | ||
28 | fido_dev_io_close_t *close; | ||
29 | fido_dev_io_read_t *read; | ||
30 | fido_dev_io_write_t *write; | ||
31 | } fido_dev_io_t; | ||
32 | |||
33 | typedef struct fido_dev_transport { | ||
34 | fido_dev_rx_t *rx; | ||
35 | fido_dev_tx_t *tx; | ||
36 | } fido_dev_transport_t; | ||
37 | |||
38 | typedef enum { | ||
39 | FIDO_OPT_OMIT = 0, /* use authenticator's default */ | ||
40 | FIDO_OPT_FALSE, /* explicitly set option to false */ | ||
41 | FIDO_OPT_TRUE, /* explicitly set option to true */ | ||
42 | } fido_opt_t; | ||
43 | |||
44 | typedef void fido_log_handler_t(const char *); | ||
45 | |||
46 | #ifdef _FIDO_INTERNAL | ||
47 | #include "packed.h" | ||
48 | #include "blob.h" | ||
49 | |||
50 | /* COSE ES256 (ECDSA over P-256 with SHA-256) public key */ | ||
51 | typedef struct es256_pk { | ||
52 | unsigned char x[32]; | ||
53 | unsigned char y[32]; | ||
54 | } es256_pk_t; | ||
55 | |||
56 | /* COSE ES256 (ECDSA over P-256 with SHA-256) (secret) key */ | ||
57 | typedef struct es256_sk { | ||
58 | unsigned char d[32]; | ||
59 | } es256_sk_t; | ||
60 | |||
61 | /* COSE RS256 (2048-bit RSA with PKCS1 padding and SHA-256) public key */ | ||
62 | typedef struct rs256_pk { | ||
63 | unsigned char n[256]; | ||
64 | unsigned char e[3]; | ||
65 | } rs256_pk_t; | ||
66 | |||
67 | /* COSE EDDSA (ED25519) */ | ||
68 | typedef struct eddsa_pk { | ||
69 | unsigned char x[32]; | ||
70 | } eddsa_pk_t; | ||
71 | |||
72 | PACKED_TYPE(fido_authdata_t, | ||
73 | struct fido_authdata { | ||
74 | unsigned char rp_id_hash[32]; /* sha256 of fido_rp.id */ | ||
75 | uint8_t flags; /* user present/verified */ | ||
76 | uint32_t sigcount; /* signature counter */ | ||
77 | /* actually longer */ | ||
78 | }) | ||
79 | |||
80 | PACKED_TYPE(fido_attcred_raw_t, | ||
81 | struct fido_attcred_raw { | ||
82 | unsigned char aaguid[16]; /* credential's aaguid */ | ||
83 | uint16_t id_len; /* credential id length */ | ||
84 | uint8_t body[]; /* credential id + pubkey */ | ||
85 | }) | ||
86 | |||
87 | typedef struct fido_attcred { | ||
88 | unsigned char aaguid[16]; /* credential's aaguid */ | ||
89 | fido_blob_t id; /* credential id */ | ||
90 | int type; /* credential's cose algorithm */ | ||
91 | union { /* credential's public key */ | ||
92 | es256_pk_t es256; | ||
93 | rs256_pk_t rs256; | ||
94 | eddsa_pk_t eddsa; | ||
95 | } pubkey; | ||
96 | } fido_attcred_t; | ||
97 | |||
98 | typedef struct fido_attstmt { | ||
99 | fido_blob_t x5c; /* attestation certificate */ | ||
100 | fido_blob_t sig; /* attestation signature */ | ||
101 | } fido_attstmt_t; | ||
102 | |||
103 | typedef struct fido_rp { | ||
104 | char *id; /* relying party id */ | ||
105 | char *name; /* relying party name */ | ||
106 | } fido_rp_t; | ||
107 | |||
108 | typedef struct fido_user { | ||
109 | fido_blob_t id; /* required */ | ||
110 | char *icon; /* optional */ | ||
111 | char *name; /* optional */ | ||
112 | char *display_name; /* required */ | ||
113 | } fido_user_t; | ||
114 | |||
115 | typedef struct fido_cred_ext { | ||
116 | int mask; /* enabled extensions */ | ||
117 | int prot; /* protection policy */ | ||
118 | } fido_cred_ext_t; | ||
119 | |||
120 | typedef struct fido_cred { | ||
121 | fido_blob_t cdh; /* client data hash */ | ||
122 | fido_rp_t rp; /* relying party */ | ||
123 | fido_user_t user; /* user entity */ | ||
124 | fido_blob_array_t excl; /* list of credential ids to exclude */ | ||
125 | fido_opt_t rk; /* resident key */ | ||
126 | fido_opt_t uv; /* user verification */ | ||
127 | fido_cred_ext_t ext; /* extensions */ | ||
128 | int type; /* cose algorithm */ | ||
129 | char *fmt; /* credential format */ | ||
130 | fido_cred_ext_t authdata_ext; /* decoded extensions */ | ||
131 | fido_blob_t authdata_cbor; /* raw cbor payload */ | ||
132 | fido_authdata_t authdata; /* decoded authdata payload */ | ||
133 | fido_attcred_t attcred; /* returned credential (key + id) */ | ||
134 | fido_attstmt_t attstmt; /* attestation statement (x509 + sig) */ | ||
135 | } fido_cred_t; | ||
136 | |||
137 | typedef struct _fido_assert_stmt { | ||
138 | fido_blob_t id; /* credential id */ | ||
139 | fido_user_t user; /* user attributes */ | ||
140 | fido_blob_t hmac_secret_enc; /* hmac secret, encrypted */ | ||
141 | fido_blob_t hmac_secret; /* hmac secret */ | ||
142 | int authdata_ext; /* decoded extensions */ | ||
143 | fido_blob_t authdata_cbor; /* raw cbor payload */ | ||
144 | fido_authdata_t authdata; /* decoded authdata payload */ | ||
145 | fido_blob_t sig; /* signature of cdh + authdata */ | ||
146 | } fido_assert_stmt; | ||
147 | |||
148 | typedef struct fido_assert { | ||
149 | char *rp_id; /* relying party id */ | ||
150 | fido_blob_t cdh; /* client data hash */ | ||
151 | fido_blob_t hmac_salt; /* optional hmac-secret salt */ | ||
152 | fido_blob_array_t allow_list; /* list of allowed credentials */ | ||
153 | fido_opt_t up; /* user presence */ | ||
154 | fido_opt_t uv; /* user verification */ | ||
155 | int ext; /* enabled extensions */ | ||
156 | fido_assert_stmt *stmt; /* array of expected assertions */ | ||
157 | size_t stmt_cnt; /* number of allocated assertions */ | ||
158 | size_t stmt_len; /* number of received assertions */ | ||
159 | } fido_assert_t; | ||
160 | |||
161 | typedef struct fido_opt_array { | ||
162 | char **name; | ||
163 | bool *value; | ||
164 | size_t len; | ||
165 | } fido_opt_array_t; | ||
166 | |||
167 | typedef struct fido_str_array { | ||
168 | char **ptr; | ||
169 | size_t len; | ||
170 | } fido_str_array_t; | ||
171 | |||
172 | typedef struct fido_byte_array { | ||
173 | uint8_t *ptr; | ||
174 | size_t len; | ||
175 | } fido_byte_array_t; | ||
176 | |||
177 | typedef struct fido_cbor_info { | ||
178 | fido_str_array_t versions; /* supported versions: fido2|u2f */ | ||
179 | fido_str_array_t extensions; /* list of supported extensions */ | ||
180 | unsigned char aaguid[16]; /* aaguid */ | ||
181 | fido_opt_array_t options; /* list of supported options */ | ||
182 | uint64_t maxmsgsiz; /* maximum message size */ | ||
183 | fido_byte_array_t protocols; /* supported pin protocols */ | ||
184 | uint64_t fwversion; /* firmware version */ | ||
185 | } fido_cbor_info_t; | ||
186 | |||
187 | typedef struct fido_dev_info { | ||
188 | char *path; /* device path */ | ||
189 | int16_t vendor_id; /* 2-byte vendor id */ | ||
190 | int16_t product_id; /* 2-byte product id */ | ||
191 | char *manufacturer; /* manufacturer string */ | ||
192 | char *product; /* product string */ | ||
193 | fido_dev_io_t io; /* i/o functions */ | ||
194 | fido_dev_transport_t transport; /* transport functions */ | ||
195 | } fido_dev_info_t; | ||
196 | |||
197 | PACKED_TYPE(fido_ctap_info_t, | ||
198 | /* defined in section 8.1.9.1.3 (CTAPHID_INIT) of the fido2 ctap spec */ | ||
199 | struct fido_ctap_info { | ||
200 | uint64_t nonce; /* echoed nonce */ | ||
201 | uint32_t cid; /* channel id */ | ||
202 | uint8_t protocol; /* ctaphid protocol id */ | ||
203 | uint8_t major; /* major version number */ | ||
204 | uint8_t minor; /* minor version number */ | ||
205 | uint8_t build; /* build version number */ | ||
206 | uint8_t flags; /* capabilities flags; see FIDO_CAP_* */ | ||
207 | }) | ||
208 | |||
209 | typedef struct fido_dev { | ||
210 | uint64_t nonce; /* issued nonce */ | ||
211 | fido_ctap_info_t attr; /* device attributes */ | ||
212 | uint32_t cid; /* assigned channel id */ | ||
213 | char *path; /* device path */ | ||
214 | void *io_handle; /* abstract i/o handle */ | ||
215 | fido_dev_io_t io; /* i/o functions */ | ||
216 | fido_dev_transport_t transport; /* transport functions */ | ||
217 | } fido_dev_t; | ||
218 | |||
219 | #else | ||
220 | typedef struct fido_assert fido_assert_t; | ||
221 | typedef struct fido_cbor_info fido_cbor_info_t; | ||
222 | typedef struct fido_cred fido_cred_t; | ||
223 | typedef struct fido_dev fido_dev_t; | ||
224 | typedef struct fido_dev_info fido_dev_info_t; | ||
225 | typedef struct es256_pk es256_pk_t; | ||
226 | typedef struct es256_sk es256_sk_t; | ||
227 | typedef struct rs256_pk rs256_pk_t; | ||
228 | typedef struct eddsa_pk eddsa_pk_t; | ||
229 | #endif /* _FIDO_INTERNAL */ | ||
230 | |||
231 | #ifdef __cplusplus | ||
232 | } /* extern "C" */ | ||
233 | #endif /* __cplusplus */ | ||
234 | |||
235 | #endif /* !_FIDO_TYPES_H */ | ||