/*- * Copyright (c) 2006 Fredrik Lindberg. * All rights reserved. * * 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 AUTHOR ``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 AUTHOR 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. */ /* * Loosley based on sample code from BioAPI and UPEK */ #include #include #include #include #include #include #include #include #include #include #include "bioapitool.h" BioAPI_HANDLE * set_bsp(const char *bsp_uuid) { BioAPI_RETURN bioReturn; BioAPI_VERSION Version; const BioAPI_UUID uuid; BioAPI_HANDLE *handle = malloc(sizeof(BioAPI_HANDLE));; bioReturn = BioAPI_GetStructuredUUID(bsp_uuid, (BioAPI_UUID *)&uuid); bioReturn = BioAPI_ModuleLoad(&uuid, 0, NULL, 0); if (bioReturn != BioAPI_OK) return (NULL); Version.Major = BioAPI_MAJOR; Version.Minor = BioAPI_MINOR; bioReturn = BioAPI_ModuleAttach(&uuid, &Version, &BioAPIMemoryFuncs, 0, 0,0,0, NULL, 0, NULL, handle); if (bioReturn != BioAPI_OK) return (NULL); return (handle); } void unload_bsp(BioAPI_HANDLE *handle, const char *bsp_uuid) { const BioAPI_UUID uuid; BioAPI_GetStructuredUUID(bsp_uuid, (BioAPI_UUID *)&uuid); BioAPI_ModuleUnload(&uuid, NULL, 0); BioAPI_ModuleDetach(*handle); free(handle); } int init_bioapi(const char *bsp_id, size_t bsp_id_len) { BioAPI_RETURN bioReturn; BioAPI_VERSION bioVersion; BioAPI_BSP_SCHEMA *bsp_schemas, *cur_bsp; BioAPI_HANDLE *handle; int elmts, elmts_r, i; bioVersion.Major = BioAPI_MAJOR; bioVersion.Minor = BioAPI_MINOR; bioReturn = BioAPI_Init(&bioVersion, 0, NULL, 0, NULL); if (bioReturn != BioAPI_OK) { if (bioReturn == BioAPIERR_H_FRAMEWORK_INCOMPATIBLE_VERSION) fprintf(stderr, "BioAPI ABI version missmatch\n"); return (-1); } return (0); } int get_bsp_list(struct bsp_list **bsp_list) { BioAPI_RETURN bio_retval; BioAPI_BSP_SCHEMA *bsp_schemas, *cur_bsp; int elmts, elmts_r, i; struct bsp_list *bsps; bio_retval = BioAPI_EnumModules(NULL, 0, &elmts, &elmts_r); if (bio_retval != BioAPI_OK) return (-1); cur_bsp = bsp_schemas = malloc(elmts * sizeof(BioAPI_BSP_SCHEMA)); if (bsp_schemas == NULL) return (-1); bio_retval = BioAPI_EnumModules(bsp_schemas, elmts, &elmts, &elmts_r); if (bio_retval != BioAPI_OK) { free(bsp_schemas); return (-1); } bsps = malloc(sizeof(struct bsp_list) * elmts_r); for (i = 0; i < elmts_r; i++) { bsps[i].bsp_index = i; bsps[i].bsp_uuid = malloc(BioAPI_PRINTABLE_UUID_LENGTH + 1); BioAPI_GetPrintableUUID((const BioAPI_UUID *)cur_bsp->ModuleId, bsps[i].bsp_uuid); bsps[i].bsp_name = strdup(cur_bsp->BSPName); bsps[i].bsp_desc = strdup(cur_bsp->Description); bsps[i].bsp_vend = strdup(cur_bsp->Vendor); cur_bsp++; } free(bsp_schemas); *bsp_list = bsps; return (elmts_r); } void destroy_bsp_list(struct bsp_list *bsps, size_t len) { int i; for (i = 0; i < len; i++) { free(bsps[i].bsp_uuid); free(bsps[i].bsp_name); free(bsps[i].bsp_desc); free(bsps[i].bsp_vend); } free(bsps); } void close_bioapi(BioAPI_HANDLE *handle) { BioAPI_Terminate(); } int create_record(BioAPI_HANDLE *handle, const char *user, const char *path) { BioAPI_RETURN bioReturn; BioAPI_BIR_HANDLE template, captured_template; BioAPI_INPUT_BIR bir; BioAPI_BIR_PTR bir_data = NULL; int fd; int nbytes; char filename[MAX_PATH]; bioReturn = BioAPI_Enroll(*handle, BioAPI_PURPOSE_ENROLL_FOR_VERIFICATION_ONLY, NULL, &captured_template, NULL, -1, NULL); bioReturn = BioAPI_GetBIRFromHandle(*handle, captured_template, &bir_data); if (bioReturn != BioAPI_OK) return (-1); snprintf(filename, MAX_PATH - 1, "%s/%s.bir", path, user); fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_EXLOCK, S_IRWXU); if (fd < 0) return (-1); /* Write header */ write(fd, &bir_data->Header, sizeof(BioAPI_BIR_HEADER)); /* Write biometric data */ write(fd, bir_data->BiometricData, (bir_data->Header.Length) - sizeof(BioAPI_BIR_HEADER)); /* Write signature if present */ if (bir_data->Signature) { write(fd, bir_data->Signature->Length, 4); write(fd, bir_data->Signature->Data, (bir_data->Header.Length)); } close(fd); free(bir_data->BiometricData); if (bir_data->Signature) { free(bir_data->Signature->Data); free(bir_data->Signature); } free(bir_data); return (0); } int remove_record(const char *username, const char *path) { char file[FILENAME_MAX]; int retval; snprintf(file, FILENAME_MAX - 1, "%s/%s.bir", path, username); retval = unlink(file); return (retval); } int verify_record(BioAPI_HANDLE *handle, const char *user, const char *path) { int fd, nbytes, retn = 0; char filename[MAX_PATH]; BioAPI_BIR_HANDLE template, bir_processed; BioAPI_BIR *bir; BioAPI_INPUT_BIR input_bir, bir_capture, bir_input_proc; BioAPI_BIR_HEADER bir_header; BioAPI_BOOL resp = 0; BioAPI_BOOL prec = BioAPI_TRUE; BioAPI_FAR far_max, far_ach; BioAPI_RETURN bioReturn; snprintf(filename, MAX_PATH - 1, "%s/%s.bir", path, user); fd = open(filename, O_RDONLY | O_EXLOCK); if (fd < 0) return (-1); bir = malloc(sizeof(BioAPI_BIR)); if (bir == NULL) return (-1); read(fd, &bir->Header, sizeof(BioAPI_BIR_HEADER)); nbytes = (bir->Header.Length) - sizeof(BioAPI_BIR_HEADER); bir->BiometricData = malloc(nbytes); if (bir->BiometricData == NULL) { free(bir); return (-1); } read(fd, bir->BiometricData, nbytes); if (read(fd, &nbytes, 4) > 0) { bir->Signature = malloc(sizeof (BioAPI_DATA)); if (bir->Signature == NULL) return (-1); bir->Signature->Length = nbytes; bir->Signature->Data = malloc((nbytes)); if (bir->Signature->Data == NULL) return (-1); read(fd, bir->Signature->Data, (nbytes)); } else { bir->Signature = NULL; } close(fd); input_bir.InputBIR.BIR = bir; input_bir.Form = BioAPI_FULLBIR_INPUT; bioReturn = BioAPI_Capture(*handle, BioAPI_PURPOSE_VERIFY, &template, -1, NULL); if (bioReturn != BioAPI_OK) { retn = -1; goto out; } bioReturn = BioAPI_GetHeaderFromHandle(*handle, template, &bir_header); if (bioReturn != BioAPI_OK) { retn = -1; goto out; } if (bir_header.Type == BioAPI_BIR_DATA_TYPE_INTERMEDIATE) { bir_capture.Form = BioAPI_BIR_HANDLE_INPUT; bir_capture.InputBIR.BIRinBSP = &template; bioReturn = BioAPI_Process(*handle, &bir_capture, &bir_processed); if (bioReturn != BioAPI_OK) { retn = -1; goto out; } bir_input_proc.Form = BioAPI_BIR_HANDLE_INPUT; bir_input_proc.InputBIR.BIRinBSP = &bir_processed; } else { bir_input_proc.Form = BioAPI_BIR_HANDLE_INPUT; bir_input_proc.InputBIR.BIRinBSP = &template; } far_max = 1; bioReturn = BioAPI_VerifyMatch(*handle, &far_max, NULL, &prec, &bir_input_proc, &input_bir, NULL, &resp, &far_ach, NULL, NULL); retn = (resp) ? 0 : 1; out: if (bir->Signature != NULL) { free(bir->Signature->Data); free(bir->Signature); } free(bir->BiometricData); free(bir); return (retn); } int verify(BioAPI_HANDLE *handle, const char *user, const char *path) { int fd, nbytes, retn = 0; int retval; char filename[MAX_PATH]; BioAPI_BIR_HANDLE template, bir_processed; BioAPI_BIR *bir; BioAPI_INPUT_BIR input_bir, bir_capture, bir_input_proc; BioAPI_BIR_HEADER bir_header; BioAPI_BOOL resp = 0; BioAPI_BOOL prec = BioAPI_TRUE; BioAPI_FAR far_max, far_ach; BioAPI_RETURN bioReturn; snprintf(filename, MAX_PATH - 1, "%s/%s.bir", path, user); fd = open(filename, O_RDONLY | O_EXLOCK); if (fd < 0) return (-1); bir = malloc(sizeof(BioAPI_BIR)); if (bir == NULL) return (-1); read(fd, &bir->Header, sizeof(BioAPI_BIR_HEADER)); nbytes = (bir->Header.Length) - sizeof(BioAPI_BIR_HEADER); bir->BiometricData = malloc(nbytes); if (bir->BiometricData == NULL) { free(bir); return (-1); } read(fd, bir->BiometricData, nbytes); if (read(fd, &nbytes, 4) > 0) { bir->Signature = malloc(sizeof (BioAPI_DATA)); if (bir->Signature == NULL) return (-1); bir->Signature->Length = nbytes; bir->Signature->Data = malloc((nbytes)); if (bir->Signature->Data == NULL) return (-1); read(fd, bir->Signature->Data, (nbytes)); } else { bir->Signature = NULL; } close(fd); input_bir.InputBIR.BIR = bir; input_bir.Form = BioAPI_FULLBIR_INPUT; far_max = 1; bioReturn = BioAPI_Verify(*handle, &far_max, NULL, &prec, &input_bir, NULL, &resp, &far_ach, NULL, NULL, -1, NULL); if (bioReturn == BioAPI_OK && resp == BioAPI_TRUE) retval = 0; else retval = 1; out: if (bir->Signature != NULL) { free(bir->Signature->Data); free(bir->Signature); } free(bir->BiometricData); free(bir); return (retval); }