2 * Fingerprint data handling and storage
3 * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <sys/types.h>
29 #include "fp_internal.h"
31 #define DIR_PERMS 0700
33 /** @defgroup print_data Stored prints
34 * Stored prints are represented by a structure named <tt>fp_print_data</tt>.
35 * Stored prints are originally obtained from an enrollment function such as
38 * This page documents the various operations you can do with a stored print.
39 * Note that by default, "stored prints" are not actually stored anywhere
40 * except in RAM. For the simple scenarios, libfprint provides a simple API
41 * for you to save and load the stored prints referring to a single user in
42 * their home directory. For more advanced users, libfprint provides APIs for
43 * you to convert print data to a byte string, and to reconstruct stored prints
44 * from such data at a later point. You are welcome to store these byte strings
45 * in any fashion that suits you.
48 static char *base_store
= NULL
;
50 static void storage_setup(void)
54 homedir
= g_getenv("HOME");
56 homedir
= g_get_home_dir();
60 base_store
= g_build_filename(homedir
, ".fprint/prints", NULL
);
61 g_mkdir_with_parents(base_store
, DIR_PERMS
);
62 /* FIXME handle failure */
65 void fpi_data_exit(void)
70 #define FP_FINGER_IS_VALID(finger) \
71 ((finger) >= LEFT_THUMB && (finger) <= RIGHT_LITTLE)
73 /* for debug messages only */
74 static const char *finger_num_to_str(enum fp_finger finger
)
76 const char *names
[] = {
77 [LEFT_THUMB
] = "left thumb",
78 [LEFT_INDEX
] = "left index",
79 [LEFT_MIDDLE
] = "left middle",
80 [LEFT_RING
] = "left ring",
81 [LEFT_LITTLE
] = "left little",
82 [RIGHT_THUMB
] = "right thumb",
83 [RIGHT_INDEX
] = "right index",
84 [RIGHT_MIDDLE
] = "right middle",
85 [RIGHT_RING
] = "right ring",
86 [RIGHT_LITTLE
] = "right little",
88 if (!FP_FINGER_IS_VALID(finger
))
93 static struct fp_print_data
*print_data_new(uint16_t driver_id
,
94 uint32_t devtype
, enum fp_print_data_type type
, size_t length
)
96 struct fp_print_data
*data
= g_malloc(sizeof(*data
) + length
);
97 fp_dbg("length=%zd driver=%02x devtype=%04x", length
, driver_id
, devtype
);
98 memset(data
, 0, sizeof(*data
));
99 data
->driver_id
= driver_id
;
100 data
->devtype
= devtype
;
102 data
->length
= length
;
106 struct fp_print_data
*fpi_print_data_new(struct fp_dev
*dev
, size_t length
)
108 struct fp_print_data
*data
= g_malloc(sizeof(*data
) + length
);
109 memset(data
, 0, sizeof(*data
));
110 return print_data_new(dev
->drv
->id
, dev
->devtype
,
111 fpi_driver_get_data_type(dev
->drv
), length
);
114 /** \ingroup print_data
115 * Convert a stored print into a unified representation inside a data buffer.
116 * You can then store this data buffer in any way that suits you, and load
117 * it back at some later time using fp_print_data_from_data().
118 * \param data the stored print
119 * \param ret output location for the data buffer. Must be freed with free()
121 * \returns the size of the freshly allocated buffer, or 0 on error.
123 API_EXPORTED
size_t fp_print_data_get_data(struct fp_print_data
*data
,
126 struct fpi_print_data_fp1
*buf
;
131 buflen
= sizeof(*buf
) + data
->length
;
132 buf
= malloc(buflen
);
136 *ret
= (unsigned char *) buf
;
137 buf
->prefix
[0] = 'F';
138 buf
->prefix
[1] = 'P';
139 buf
->prefix
[2] = '1';
140 buf
->driver_id
= GUINT16_TO_LE(data
->driver_id
);
141 buf
->devtype
= GUINT32_TO_LE(data
->devtype
);
142 buf
->data_type
= data
->type
;
143 memcpy(buf
->data
, data
->data
, data
->length
);
147 /** \ingroup print_data
148 * Load a stored print from a data buffer. The contents of said buffer must
149 * be the untouched contents of a buffer previously supplied to you by the
150 * fp_print_data_get_data() function.
151 * \param buf the data buffer
152 * \param buflen the length of the buffer
153 * \returns the stored print represented by the data, or NULL on error. Must
154 * be freed with fp_print_data_free() after use.
156 API_EXPORTED
struct fp_print_data
*fp_print_data_from_data(unsigned char *buf
,
159 struct fpi_print_data_fp1
*raw
= (struct fpi_print_data_fp1
*) buf
;
160 size_t print_data_len
;
161 struct fp_print_data
*data
;
163 fp_dbg("buffer size %zd", buflen
);
164 if (buflen
< sizeof(*raw
))
167 if (strncmp(raw
->prefix
, "FP1", 3) != 0) {
168 fp_dbg("bad header prefix");
172 print_data_len
= buflen
- sizeof(*raw
);
173 data
= print_data_new(GUINT16_FROM_LE(raw
->driver_id
),
174 GUINT32_FROM_LE(raw
->devtype
), raw
->data_type
, print_data_len
);
175 memcpy(data
->data
, raw
->data
, print_data_len
);
179 static char *get_path_to_storedir(uint16_t driver_id
, uint32_t devtype
)
184 g_snprintf(idstr
, sizeof(idstr
), "%04x", driver_id
);
185 g_snprintf(devtypestr
, sizeof(devtypestr
), "%08x", devtype
);
187 return g_build_filename(base_store
, idstr
, devtypestr
, NULL
);
190 static char *__get_path_to_print(uint16_t driver_id
, uint32_t devtype
,
191 enum fp_finger finger
)
197 g_snprintf(fingername
, 2, "%x", finger
);
199 dirpath
= get_path_to_storedir(driver_id
, devtype
);
200 path
= g_build_filename(dirpath
, fingername
, NULL
);
205 static char *get_path_to_print(struct fp_dev
*dev
, enum fp_finger finger
)
207 return __get_path_to_print(dev
->drv
->id
, dev
->devtype
, finger
);
210 /** \ingroup print_data
211 * Saves a stored print to disk, assigned to a specific finger. Even though
212 * you are limited to storing only the 10 human fingers, this is a
213 * per-device-type limit. For example, you can store the users right index
214 * finger from a DigitalPersona scanner, and you can also save the right index
215 * finger from a UPEK scanner. When you later come to load the print, the right
216 * one will be automatically selected.
218 * This function will unconditionally overwrite a fingerprint previously
219 * saved for the same finger and device type. The print is saved in a hidden
220 * directory beneath the current user's home directory.
221 * \param data the stored print to save to disk
222 * \param finger the finger that this print corresponds to
223 * \returns 0 on success, non-zero on error.
225 API_EXPORTED
int fp_print_data_save(struct fp_print_data
*data
,
226 enum fp_finger finger
)
238 fp_dbg("save %s print from driver %04x", finger_num_to_str(finger
),
240 len
= fp_print_data_get_data(data
, &buf
);
244 path
= __get_path_to_print(data
->driver_id
, data
->devtype
, finger
);
245 dirpath
= g_path_get_dirname(path
);
246 r
= g_mkdir_with_parents(dirpath
, DIR_PERMS
);
248 fp_err("couldn't create storage directory");
254 fp_dbg("saving to %s", path
);
255 g_file_set_contents(path
, buf
, len
, &err
);
261 fp_err("save failed: %s", err
->message
);
263 /* FIXME interpret error codes */
270 gboolean
fpi_print_data_compatible(uint16_t driver_id1
, uint32_t devtype1
,
271 enum fp_print_data_type type1
, uint16_t driver_id2
, uint32_t devtype2
,
272 enum fp_print_data_type type2
)
274 if (driver_id1
!= driver_id2
) {
275 fp_dbg("driver ID mismatch: %02x vs %02x", driver_id1
, driver_id2
);
279 if (devtype1
!= devtype2
) {
280 fp_dbg("devtype mismatch: %04x vs %04x", devtype1
, devtype2
);
284 if (type1
!= type2
) {
285 fp_dbg("type mismatch: %d vs %d", type1
, type2
);
292 static int load_from_file(char *path
, struct fp_print_data
**data
)
297 struct fp_print_data
*fdata
;
299 fp_dbg("from %s", path
);
300 g_file_get_contents(path
, &contents
, &length
, &err
);
303 fp_err("%s load failed: %s", path
, err
->message
);
305 /* FIXME interpret more error codes */
306 if (r
== G_FILE_ERROR_NOENT
)
312 fdata
= fp_print_data_from_data(contents
, length
);
320 /** \ingroup print_data
321 * Loads a previously stored print from disk. The print must have been saved
322 * earlier using the fp_print_data_save() function.
324 * A return code of -ENOENT indicates that the fingerprint requested could not
325 * be found. Other error codes (both positive and negative) are possible for
326 * obscure error conditions (e.g. corruption).
328 * \param dev the device you are loading the print for
329 * \param finger the finger of the file you are loading
330 * \param data output location to put the corresponding stored print. Must be
331 * freed with fp_print_data_free() after use.
332 * \returns 0 on success, non-zero on error
334 API_EXPORTED
int fp_print_data_load(struct fp_dev
*dev
,
335 enum fp_finger finger
, struct fp_print_data
**data
)
338 struct fp_print_data
*fdata
;
344 path
= get_path_to_print(dev
, finger
);
345 r
= load_from_file(path
, &fdata
);
350 if (!fp_dev_supports_print_data(dev
, fdata
)) {
351 fp_err("print data is not compatible!");
352 fp_print_data_free(fdata
);
360 /** \ingroup print_data
361 * Attempts to load a stored print based on a \ref dscv_print
362 * "discovered print" record.
364 * A return code of -ENOENT indicates that the file referred to by the
365 * discovered print could not be found. Other error codes (both positive and
366 * negative) are possible for obscure error conditions (e.g. corruption).
368 * \param print the discovered print
369 * \param data output location to point to the corresponding stored print. Must
370 * be freed with fp_print_data_free() after use.
371 * \returns 0 on success, non-zero on error.
373 API_EXPORTED
int fp_print_data_from_dscv_print(struct fp_dscv_print
*print
,
374 struct fp_print_data
**data
)
376 return load_from_file(print
->path
, data
);
379 /** \ingroup print_data
380 * Frees a stored print. Must be called when you are finished using the print.
381 * \param data the stored print to destroy. If NULL, function simply returns.
383 API_EXPORTED
void fp_print_data_free(struct fp_print_data
*data
)
388 /** \ingroup print_data
389 * Gets the \ref driver_id "driver ID" for a stored print. The driver ID
390 * indicates which driver the print originally came from. The print is
391 * only usable with a device controlled by that driver.
392 * \param data the stored print
393 * \returns the driver ID of the driver compatible with the print
395 API_EXPORTED
uint16_t fp_print_data_get_driver_id(struct fp_print_data
*data
)
397 return data
->driver_id
;
400 /** \ingroup print_data
401 * Gets the \ref devtype "devtype" for a stored print. The devtype represents
402 * which type of device under the parent driver is compatible with the print.
403 * \param data the stored print
404 * \returns the devtype of the device range compatible with the print
406 API_EXPORTED
uint32_t fp_print_data_get_devtype(struct fp_print_data
*data
)
408 return data
->devtype
;
411 /** @defgroup dscv_print Print discovery
412 * The \ref print_data "stored print" documentation detailed a simple API
413 * for storing per-device prints for a single user, namely
414 * fp_print_data_save(). It also detailed a load function,
415 * fp_print_data_load(), but usage of this function is limited to scenarios
416 * where you know which device you would like to use, and you know which
417 * finger you are looking to verify.
419 * In other cases, it would be more useful to be able to enumerate all
420 * previously saved prints, potentially even before device discovery. These
421 * functions are designed to offer this functionality to you.
423 * Discovered prints are stored in a <tt>dscv_print</tt> structure, and you
424 * can use functions documented below to access some information about these
425 * prints. You can determine if a discovered print appears to be compatible
426 * with a device using functions such as fp_dscv_dev_supports_dscv_print() and
427 * fp_dev_supports_dscv_print().
429 * When you are ready to use the print, you can load it into memory in the form
430 * of a stored print by using the fp_print_data_from_dscv_print() function.
432 * You may have noticed the use of the word "appears" in the above paragraphs.
433 * libfprint performs print discovery simply by examining the file and
434 * directory structure of libfprint's private data store. It does not examine
435 * the actual prints themselves. Just because a print has been discovered
436 * and appears to be compatible with a certain device does not necessarily mean
437 * that it is usable; when you come to load or use it, under unusual
438 * circumstances it may turn out that the print is corrupt or not for the
439 * device that it appeared to be. Also, it is possible that the print may have
440 * been deleted by the time you come to load it.
443 static GSList
*scan_dev_store_dir(char *devpath
, uint16_t driver_id
,
444 uint32_t devtype
, GSList
*list
)
448 struct fp_dscv_print
*print
;
450 GDir
*dir
= g_dir_open(devpath
, 0, &err
);
452 fp_err("opendir %s failed: %s", devpath
, err
->message
);
457 while (ent
= g_dir_read_name(dir
)) {
458 /* ent is an 1 hex character fp_finger code */
460 enum fp_finger finger
;
463 if (*ent
== 0 || strlen(ent
) != 1)
466 val
= g_ascii_strtoull(ent
, &endptr
, 16);
467 if (endptr
== ent
|| !FP_FINGER_IS_VALID(val
)) {
468 fp_dbg("skipping print file %s", ent
);
472 finger
= (enum fp_finger
) val
;
473 print
= g_malloc(sizeof(*print
));
474 print
->driver_id
= driver_id
;
475 print
->devtype
= devtype
;
476 print
->path
= g_build_filename(devpath
, ent
, NULL
);
477 print
->finger
= finger
;
478 list
= g_slist_prepend(list
, print
);
485 static GSList
*scan_driver_store_dir(char *drvpath
, uint16_t driver_id
,
491 GDir
*dir
= g_dir_open(drvpath
, 0, &err
);
493 fp_err("opendir %s failed: %s", drvpath
, err
->message
);
498 while (ent
= g_dir_read_name(dir
)) {
499 /* ent is an 8 hex character devtype */
505 if (*ent
== 0 || strlen(ent
) != 8)
508 val
= g_ascii_strtoull(ent
, &endptr
, 16);
510 fp_dbg("skipping devtype %s", ent
);
514 devtype
= (uint32_t) val
;
515 path
= g_build_filename(drvpath
, ent
, NULL
);
516 list
= scan_dev_store_dir(path
, driver_id
, devtype
, list
);
524 /** \ingroup dscv_print
525 * Scans the users home directory and returns a list of prints that were
526 * previously saved using fp_print_data_save().
527 * \returns a NULL-terminated list of discovered prints, must be freed with
528 * fp_dscv_prints_free() after use.
530 API_EXPORTED
struct fp_dscv_print
**fp_discover_prints(void)
535 GSList
*tmplist
= NULL
;
537 unsigned int tmplist_len
;
538 struct fp_dscv_print
**list
;
544 dir
= g_dir_open(base_store
, 0, &err
);
546 fp_err("opendir %s failed: %s", base_store
, err
->message
);
551 while (ent
= g_dir_read_name(dir
)) {
552 /* ent is a 4 hex digit driver_id */
558 if (*ent
== 0 || strlen(ent
) != 4)
561 val
= g_ascii_strtoull(ent
, &endptr
, 16);
563 fp_dbg("skipping drv id %s", ent
);
567 driver_id
= (uint16_t) val
;
568 path
= g_build_filename(base_store
, ent
, NULL
);
569 tmplist
= scan_driver_store_dir(path
, driver_id
, tmplist
);
574 tmplist_len
= g_slist_length(tmplist
);
575 list
= g_malloc(sizeof(*list
) * (tmplist_len
+ 1));
577 for (i
= 0; i
< tmplist_len
; i
++, elem
= g_slist_next(elem
))
578 list
[i
] = elem
->data
;
579 list
[tmplist_len
] = NULL
; /* NULL-terminate */
581 g_slist_free(tmplist
);
585 /** \ingroup dscv_print
586 * Frees a list of discovered prints. This function also frees the discovered
587 * prints themselves, so make sure you do not use any discovered prints
588 * after calling this function.
589 * \param prints the list of discovered prints. If NULL, function simply
592 API_EXPORTED
void fp_dscv_prints_free(struct fp_dscv_print
**prints
)
595 struct fp_dscv_print
*print
;
600 for (i
= 0; print
= prints
[i
]; i
++) {
608 /** \ingroup dscv_print
609 * Gets the \ref driver_id "driver ID" for a discovered print. The driver ID
610 * indicates which driver the print originally came from. The print is only
611 * usable with a device controlled by that driver.
612 * \param print the discovered print
613 * \returns the driver ID of the driver compatible with the print
615 API_EXPORTED
uint16_t fp_dscv_print_get_driver_id(struct fp_dscv_print
*print
)
617 return print
->driver_id
;
620 /** \ingroup dscv_print
621 * Gets the \ref devtype "devtype" for a discovered print. The devtype
622 * represents which type of device under the parent driver is compatible
624 * \param print the discovered print
625 * \returns the devtype of the device range compatible with the print
627 API_EXPORTED
uint32_t fp_dscv_print_get_devtype(struct fp_dscv_print
*print
)
629 return print
->devtype
;
632 /** \ingroup dscv_print
633 * Gets the finger code for a discovered print.
634 * \param print discovered print
635 * \returns a finger code from #fp_finger
637 API_EXPORTED
enum fp_finger
fp_dscv_print_get_finger(struct fp_dscv_print
*print
)
639 return print
->finger
;