Beispiel #1
0
BioAPI_RETURN BioAPI mdsutil_GetRecordByUuidAndDeviceId(CSSM_DL_DB_HANDLE hDLDB,
												   char* UuidStr,
												   uint32 DeviceId,
												   CSSM_DB_RECORDTYPE RecordType,
												   uint32 NumAttributes,
												   CSSM_HANDLE_PTR ResultsHandle,
												   CSSM_DB_ATTRIBUTE_DATA *OutputAttributeData)
{
	BioAPI_RETURN retValue = CSSM_OK;
	CSSM_QUERY Query;
	CSSM_SELECTION_PREDICATE Predicate[2];

	memset (&Query, 0, sizeof (CSSM_QUERY));
	memset (&Predicate[0], 0, sizeof (CSSM_SELECTION_PREDICATE));
	memset (&Predicate[1], 0, sizeof (CSSM_SELECTION_PREDICATE));

	Query.RecordType = RecordType;
	Query.Conjunctive = CSSM_DB_AND;
	Query.NumSelectionPredicates = 2;

	Query.SelectionPredicate = Predicate;
	Query.QueryLimits.TimeLimit = CSSM_QUERY_TIMELIMIT_NONE;
	Query.QueryLimits.SizeLimit = CSSM_QUERY_SIZELIMIT_NONE;
	Query.QueryFlags = 0;

	Predicate[0].DbOperator = CSSM_DB_EQUAL;
	Predicate[0].Attribute.Info = s_BioApiAttrInfo_ModuleId;
	Predicate[0].Attribute.Value = (CSSM_DATA *) BioAPI_malloc(sizeof (CSSM_DATA), NULL);
	if (Predicate[0].Attribute.Value == NULL)
		return CSSM_ERRCODE_MEMORY_ERROR;
	Predicate[0].Attribute.NumberOfValues = 1;
	Predicate[0].Attribute.Value->Data = (unsigned char *)UuidStr;
	Predicate[0].Attribute.Value->Length = (uint32)strlen (UuidStr) + 1;

	Predicate[1].DbOperator = CSSM_DB_EQUAL;
	Predicate[1].Attribute.Info = s_BioApiAttrInfo_DeviceId;
	Predicate[1].Attribute.Value = (CSSM_DATA *) BioAPI_malloc(sizeof (CSSM_DATA), NULL);
	if (Predicate[1].Attribute.Value == NULL)
	{
		BioAPI_free(Predicate[0].Attribute.Value, NULL);
		return CSSM_ERRCODE_MEMORY_ERROR;
	}
	Predicate[1].Attribute.NumberOfValues = 1;
	Predicate[1].Attribute.Value->Data = (unsigned char *)&DeviceId;
	Predicate[1].Attribute.Value->Length = (uint32)sizeof(uint32);

	retValue = mdsutil_GetRecord(hDLDB,
								 Query,
								 RecordType,
								 NumAttributes,
								 ResultsHandle,
								 OutputAttributeData);

	BioAPI_free(Predicate[0].Attribute.Value, NULL);
	BioAPI_free(Predicate[1].Attribute.Value, NULL);

	return retValue;
}
Beispiel #2
0
BioAPI_RETURN BioAPI
mdsutil_GetModulePath (CSSM_DATA ModuleName, CSSM_DATA ModuleSearchPath, CSSM_DATA_PTR ModulePath)
{
	uint8 *SearchPtr;
	uint8 *ptr;
	uint32 len;
	CSSM_DATA tmpPath;
	struct _stat st;

	// Check for blank search path; just use the system search path
	if (ModuleSearchPath.Length == 0)
	{
		if ((ModulePath->Data = (uint8*)BioAPI_malloc (ModuleName.Length, NULL)) == NULL)
			return (CSSM_ERRCODE_MEMORY_ERROR);
		strcpy ((char*) ModulePath->Data, (char*) ModuleName.Data);
		ModulePath->Length = ModuleName.Length;
		return BioAPI_OK;
	} // if

	len = ModuleSearchPath.Length + ModuleName.Length + 2;
	if ((ptr = (uint8*)BioAPI_malloc (len, NULL)) == NULL)
		return (CSSM_ERRCODE_MEMORY_ERROR);

	SearchPtr = ModuleSearchPath.Data;
	tmpPath.Data = ModuleSearchPath.Data;
	tmpPath.Length = ModuleSearchPath.Length;

	while (SearchPtr) {
		SearchPtr = memchr (tmpPath.Data, PATH_SEPARATOR, tmpPath.Length);
		if (SearchPtr != NULL) {
			tmpPath.Length = (uint32)(SearchPtr - tmpPath.Data);
			SearchPtr++;			/* Skip the PATH_SEPARATOR */
		} else {
			/*
			 * get rid of the null character at the end of search path, if any.
			 */
			if (tmpPath.Data[tmpPath.Length-1] == '\0')
				tmpPath.Length--;
		}

		ModulePath->Data = ptr;
		memcpy(ptr, tmpPath.Data, tmpPath.Length);
		ptr = ptr + tmpPath.Length;
		*ptr++ = DIRECTORY_SEPARATOR;
		memcpy(ptr, ModuleName.Data, ModuleName.Length);		/* copy relative path */
		ptr = ptr + ModuleName.Length;					/* move to end of string */
		*ptr = '\0';									/* null terminate */
		ModulePath->Length = (uint32)(ptr - ModulePath->Data);
		/*
		 * stat the file and find out if we have found it.
		 * If yes, then return else continue searching the
		 * search path.
		 */
		if ((_stat((const char *)ModulePath->Data, &st)) == 0)
			return (CSSM_OK);

		tmpPath.Data = SearchPtr;
		if(SearchPtr != NULL)
			tmpPath.Length = (uint32)(ModuleSearchPath.Length - (uint32)(SearchPtr - ModuleSearchPath.Data));
	}

	return (CSSM_ERRCODE_MDS_ERROR);
}
Beispiel #3
0
BioAPI_RETURN BioAPI mdsutil_DeleteRecordByUuid(CSSM_DL_DB_HANDLE hDLDB,
											   const BioAPI_UUID *uuid,
											   CSSM_DB_RECORDTYPE RecordType)
{
	CSSM_QUERY Query;
	CSSM_SELECTION_PREDICATE Predicate;
	CSSM_DB_UNIQUE_RECORD_PTR RecordId = NULL;
	BioAPI_RETURN retValue = CSSM_OK;
	CSSM_HANDLE ResultsHandle = 0;
	char UuidStr[BioAPI_PRINTABLE_UUID_LENGTH];

	memset (&Query, 0, sizeof (CSSM_QUERY));
	memset (&Predicate, 0, sizeof (CSSM_SELECTION_PREDICATE));
	Query.RecordType = RecordType;
	Query.Conjunctive = CSSM_DB_NONE;
	Query.NumSelectionPredicates = 1;
	Query.SelectionPredicate = &Predicate;
	Query.QueryLimits.TimeLimit = CSSM_QUERY_TIMELIMIT_NONE;
	Query.QueryLimits.SizeLimit = CSSM_QUERY_SIZELIMIT_NONE;
	Query.QueryFlags = 0;

	Predicate.DbOperator = CSSM_DB_EQUAL;

	/*
	 * Convert the Uuid to a string.
	 */
	BioAPI_GetPrintableUUID (uuid, UuidStr);

	Predicate.Attribute.Info = s_BioApiAttrInfo_ModuleId;
	Predicate.Attribute.Value = (CSSM_DATA *) BioAPI_malloc(sizeof (CSSM_DATA), 0);
	if (Predicate.Attribute.Value == NULL)
		return (CSSM_ERRCODE_MEMORY_ERROR);
	Predicate.Attribute.NumberOfValues = 1;
	Predicate.Attribute.Value->Data = (unsigned char *)UuidStr;
	Predicate.Attribute.Value->Length = (uint32)strlen (UuidStr) + 1;

	if( !IsBadCodePtr((CSSM_PROC_ADDR)MDSFuncs.DataGetFirst))
		retValue = MDSFuncs.DataGetFirst(hDLDB, /* DLDBHandle */
											 &Query,
											 &ResultsHandle,
											 NULL,
											 NULL,
											 &RecordId);

	while (CSSM_OK == retValue)
	{
		if( !IsBadCodePtr((CSSM_PROC_ADDR)MDSFuncs.DataDelete))
			retValue = MDSFuncs.DataDelete(hDLDB, RecordId);

		if( !IsBadCodePtr((CSSM_PROC_ADDR)MDSFuncs.FreeUniqueRecord))
			MDSFuncs.FreeUniqueRecord(hDLDB, RecordId);

		if( !IsBadCodePtr((CSSM_PROC_ADDR)MDSFuncs.DataGetNext))
			retValue = MDSFuncs.DataGetNext(hDLDB, /* DLDBHandle */
											ResultsHandle,
											NULL,
											NULL,
											&RecordId);
	}

	if (CSSMERR_DL_ENDOFDATA == retValue)
	{
		retValue = CSSM_OK;
	}

	MDSFuncs.DataAbortQuery( hDLDB, ResultsHandle );
	BioAPI_free(Predicate.Attribute.Value, NULL);
	return (retValue);
}
Beispiel #4
0
BioAPI_RETURN _biospi_Process(
			ADDIN_ATTACH_DATA			*pAttachData,
			const void		 *pLoadData,
			const BioAPI_BIR		  *pBIRtoProcess,
			BioAPI_BIR_HANDLE_PTR	   ProcessedBIR )
{
	BIR_LIST_NODE  *pOldList			 = NULL,
				   *pHeadNode			 = NULL;
	BIO_DATA_HEADER bioDataHeader;
	uint32			newBioDataLength;
	uint8		   *pNewBioData;

	/*--------------------------------*
	 * Check for the proper BIR flags *
	 *--------------------------------*/

	/*----------------------------------------------------------------------------*
	 * Note about signed BIRs: if this BSP could somehow support signed BIRs, the *
	 * signature would be verified at this point.  Note that this means that flag *
	 * can be discarded below to account for the check which could occur at this  *
	 * point in the future, if signatures were implemented here.				  *
	 *----------------------------------------------------------------------------*/

	/* Only raw BIRs should be processed. Signed raw data is OK,
	 * so strip that flag off before the check.	 This is to allow
	 * for the possibility of signed BIRs in the future; see above. */
	if (pBIRtoProcess->Header.Type & ~BioAPI_BIR_DATA_TYPE_SIGNED
			!= BioAPI_BIR_DATA_TYPE_RAW)
		return (BioAPIERR_BSP_INVALID_BIR);

	/* Only enrollment purpose is supported.  Since the Verify
	 * function requires that the BIR captured for verification comes
	 * to it with the password in plaintext, even the
	 * CSSM_HRS_PURPOSE_VERIFY is not supported in this function.
	 * When a BIR is "processed" within the context of this BSP,
	 * it can then be used to "enroll" a BIR for a payload which is
	 * stored in plaintext, instead of encrypted. */
	if (BioAPI_PURPOSE_ENROLL_FOR_VERIFICATION_ONLY !=
			pBIRtoProcess->Header.PurposeMask)
		return (BioAPIERR_BSP_PURPOSE_NOT_SUPPORTED);

	/* Only BIRs utilizing the proper biometric data format can be used */
	if (BIO_DATA_FORMAT_ID	  != LocalEndian2 (pBIRtoProcess->Header.Format.FormatID) ||
		BIO_DATA_FORMAT_OWNER != LocalEndian2 (pBIRtoProcess->Header.Format.FormatOwner))
		return (BioAPIERR_BSP_UNSUPPORTED_FORMAT);

	/*----------------------*
	 * Create processed BIR *
	 *----------------------*/

	/* copy the biometric header */
	port_memcpy((void*)&bioDataHeader, (void*)pBIRtoProcess->BiometricData,
				sizeof(BIO_DATA_HEADER));

	/* calc length of biometric data */
	newBioDataLength	  = bioDataHeader.PWLength +
						  bioDataHeader.PayloadLength +
						  sizeof(BIO_DATA_HEADER);

	/* allocate memory for the "biometric" data */
	pNewBioData			 = BioAPI_malloc(newBioDataLength, NULL);
	if (NULL == pNewBioData)
		return (BioAPIERR_BSP_MEMORY_ERROR);

	/* In this biometric format, the header describing the length
	 * of the password and payload, the cryptographic salts, and the
	 * cryptographic initialization data vector is included in the
	 * opaque biometric data first, followed by the password, then
	 * the payload.	 We copy the headers and PW data over first */
	port_memcpy((void*)pNewBioData, (void*)&bioDataHeader,
				sizeof(BIO_DATA_HEADER));

	port_memcpy((void*)(pNewBioData + sizeof(BIO_DATA_HEADER)),
				(void*)(pBIRtoProcess->BiometricData + sizeof(BIO_DATA_HEADER)),
				bioDataHeader.PWLength);

	/* Then we copy over the payload */
	port_memcpy((void*)(pNewBioData + sizeof(BIO_DATA_HEADER) + bioDataHeader.PWLength),
				(void*)(pBIRtoProcess->BiometricData + sizeof(BIO_DATA_HEADER) + bioDataHeader.PWLength),
				bioDataHeader.PayloadLength);


	/* Keep track of BIR in addin until function FreeBIRHandle(...)
	 * releases it */

	pOldList = pAttachData->BIRList;
	pAttachData->BIRList = pHeadNode =
		(BIR_LIST_NODE*) BioAPI_malloc(sizeof(BIR_LIST_NODE), NULL);
	if (NULL == pHeadNode)
	{
		BioAPI_free (pNewBioData, NULL);
		return (BioAPIERR_BSP_MEMORY_ERROR);
	}
	pHeadNode->NextNode		= (void*)pOldList;

	/* Build BIR Header */
	pHeadNode->BIRHandle  = *ProcessedBIR	 = pAttachData->HandleIndex++;
	pHeadNode->BIR.Header.HeaderVersion		 = BIR_HEADER_VERSION;
	pHeadNode->BIR.Header.Type = BioAPI_BIR_DATA_TYPE_PROCESSED;
	pHeadNode->BIR.Header.Format.FormatOwner = LittleEndian2 (BIO_DATA_FORMAT_OWNER);
	pHeadNode->BIR.Header.Format.FormatID	 = LittleEndian2 (BIO_DATA_FORMAT_ID);
	pHeadNode->BIR.Header.Quality			 = 100; /* by definition */
	pHeadNode->BIR.Header.FactorsMask		 = LittleEndian4 (BioAPI_FACTOR_PASSWORD);

	/* The input BIR's header has the length already converted to little-endian */
	pHeadNode->BIR.Header.Length   = pBIRtoProcess->Header.Length;

	/* This BIR is just another incarnation of the input BIR -
	 * it has the same purpose */
	pHeadNode->BIR.Header.PurposeMask		 = pBIRtoProcess->Header.PurposeMask;

	/* Finish BIR */
	pHeadNode->BIR.Signature	 = NULL;
	pHeadNode->BIR.BiometricData = (BioAPI_BIR_BIOMETRIC_DATA*)pNewBioData;

	return BioAPI_OK;
}
Beispiel #5
0
BioAPI_RETURN _biospi_CreateTemplate(
			ADDIN_ATTACH_DATA			*pAttachData,
			const void		 *pLoadData,
			const BioAPI_BIR		  *pBIRtoWrap,
			BioAPI_BIR_HANDLE_PTR	   NewTemplate,
			const BioAPI_DATA			  *Payload )
{
	BIR_LIST_NODE  *pOldList					 = NULL,
				   *pHeadNode					 = NULL;
	uint8		   *pNewBioData					 = NULL;
	uint32			newBioDataLength			 = 0;
	BIO_DATA_HEADER bioDataHeader;

	/*---------------------------------------------------------*
	 * Only BIRs with the purpose of enrollment should be used *
	 *---------------------------------------------------------*/

	if (BioAPI_PURPOSE_ENROLL_FOR_VERIFICATION_ONLY
			!= pBIRtoWrap->Header.PurposeMask)
		return (BioAPIERR_BSP_INVALID_BIR);

	/*----------------------------------------------------------------------*
	 * Only BIRs created using the proper biometric data format can be used *
	 *----------------------------------------------------------------------*/

	if (BIO_DATA_FORMAT_ID	  != LocalEndian2 (pBIRtoWrap->Header.Format.FormatID) ||
		BIO_DATA_FORMAT_OWNER != LocalEndian2 (pBIRtoWrap->Header.Format.FormatOwner))
		return (BioAPIERR_BSP_UNSUPPORTED_FORMAT);

	/*------------------------------------------------*
	 * Only raw and processed BIRs should be accepted *
	 *------------------------------------------------*/

	/*---------------------------------------------------*
	 * Rewrap with payload, but don't encrypt - we no	 *
	 * longer have plaintext password for key derivation *
	 *---------------------------------------------------*/

	/* Retrieve the opaque header information from the BIR */
	port_memcpy((void*)&bioDataHeader, (void*)pBIRtoWrap->BiometricData,
				sizeof(BIO_DATA_HEADER));

	/* New biometric data will include the old data plus any payload */
	if (Payload)
		bioDataHeader.PayloadLength = Payload->Length;
	else
		bioDataHeader.PayloadLength = 0;
	newBioDataLength			= bioDataHeader.PWLength +
								  bioDataHeader.PayloadLength +
								  sizeof(BIO_DATA_HEADER);
	pNewBioData					= BioAPI_malloc(newBioDataLength, NULL);
	if (!pNewBioData)
		return (BioAPIERR_BSP_MEMORY_ERROR);

	/*---------------------------------------------------*
	 * Move the payload into the addin's memory space,	 *
	 * so that it can be included in a new template BIR	 *
	 *---------------------------------------------------*/

	/* In this biometric format, the header describing the length
	 * of the password and payload, the cryptographic salts, and the
	 * cryptographic initialization data vector is included in the
	 * opaque biometric data first, followed by the password, then
	 * the payload.	 We copy the headers and PW data over first */
	port_memcpy((void*)pNewBioData, (void*)&bioDataHeader,
				sizeof(BIO_DATA_HEADER));

	port_memcpy((void*)(pNewBioData + sizeof(BIO_DATA_HEADER)),
				(void*)(pBIRtoWrap->BiometricData + sizeof(BIO_DATA_HEADER)),
				bioDataHeader.PWLength);

	/* Then we copy over the payload */
	if (Payload)
	{
		port_memcpy((void*)(pNewBioData + sizeof(BIO_DATA_HEADER) + bioDataHeader.PWLength),
						(void*)Payload->Data, Payload->Length);
	} // if

	/*----------------------------------------------------*
	 * Build template with new biometric data and payload *
	 *----------------------------------------------------*/

	/* The assumption, at this point, is that for either case of BIR
	 * input, raw or processed, that pNewBioData contains the opaque
	 * data field to be stored, that newBioDataLength is the length
	 * of that field. */

	/* Keep track of BIR in addin until function FreeBIRHandle(...) releases it */

	pOldList = pAttachData->BIRList;
	pAttachData->BIRList = pHeadNode =
		(BIR_LIST_NODE*) BioAPI_malloc(sizeof(BIR_LIST_NODE), NULL);
	pHeadNode->NextNode		= (void*)pOldList;

	/* Build BIR Header */
	pHeadNode->BIRHandle  = *NewTemplate	 = pAttachData->HandleIndex++;
	pHeadNode->BIR.Header.HeaderVersion		 = BIR_HEADER_VERSION;
	pHeadNode->BIR.Header.Type = BioAPI_BIR_DATA_TYPE_PROCESSED;
	pHeadNode->BIR.Header.Format.FormatOwner = LittleEndian2 (BIO_DATA_FORMAT_OWNER);
	pHeadNode->BIR.Header.Format.FormatID	 = LittleEndian2 (BIO_DATA_FORMAT_ID);
	pHeadNode->BIR.Header.Quality			 = 100; /* by definition */
	pHeadNode->BIR.Header.FactorsMask		 = LittleEndian4 (BioAPI_FACTOR_PASSWORD);
	pHeadNode->BIR.Header.PurposeMask		 = BioAPI_PURPOSE_VERIFY;

	/* bio data length includes the format header, the password, and the payload,
	 * while the BIR header length includes all this and the BioAPI BIR header's length */
	pHeadNode->BIR.Header.Length = LittleEndian4 (newBioDataLength + sizeof(BioAPI_BIR_HEADER));

	/* Finish the BIR */
	pHeadNode->BIR.Signature	 = NULL;
	pHeadNode->BIR.BiometricData = (BioAPI_BIR_BIOMETRIC_DATA*)pNewBioData;

	return BioAPI_OK;
}
Beispiel #6
0
BioAPI_RETURN _biospi_Capture(
					ADDIN_ATTACH_DATA		*pAttachData,
					BioAPI_BIR_PURPOSE	   Purpose,
					BioAPI_BIR_HANDLE_PTR  CapturedBIR)
{
	BIR_LIST_NODE	*pOldList		   = NULL,
					*pHeadNode		   = NULL;
	uint32			 capturedBIRLength = 0;
	BIO_DATA_HEADER	 bioDataHeader;

#ifdef WIN32

	INT_PTR dialogRetVal = 0;
	HANDLE	dllHandle;

#endif

	/*---------------------------------------*
	 * Get the password from the user.		 *
	 * Start of platform specific code here! *
	 *---------------------------------------*/

/*------------------------------------------------------------------------
 * WIN32
 *-----------------------------------------------------------------------*/

	#ifdef WIN32
	/*---------------------------------------*
	 * Create Dialog and prompt for password *
	 *---------------------------------------*/

	/* Windows will find this library in the system directory
	 * where the .dll is installed */
	dllHandle = LoadLibrary(BSP_SELF_CHECK_SECTION);

	if (IDOK != (dialogRetVal = DialogBox(
						dllHandle,	MAKEINTRESOURCE(IDD_PWDIALOG),
						NULL,		(DLGPROC)CapturePassword)))
	{
		/* Operation failed; password wasn't captured */
		 return (BioAPIERR_BSP_UNABLE_TO_CAPTURE);
	}

	#endif	// WIN32 defined

/*------------------------------------------------------------------------*/

	/*---------------------------------------*
	 * End of platform specific code. Assume *
	 * now that the password is stored in	 *
	 * the global buffer inputPassword.		 *
	 *---------------------------------------*/

	/* Keep track of BIR in addin until function FreeBIRHandle(...)
	 * releases it */

	pOldList = pAttachData->BIRList;
	pAttachData->BIRList = pHeadNode =
		(BIR_LIST_NODE*) BioAPI_malloc(sizeof(BIR_LIST_NODE), NULL);
	pHeadNode->NextNode		= (void*)pOldList;

	/*------------------*
	 * Build BIR Header *
	 *------------------*/
	pHeadNode->BIRHandle  = *CapturedBIR	 = pAttachData->HandleIndex++;
	pHeadNode->BIR.Header.HeaderVersion		 = BIR_HEADER_VERSION;
	pHeadNode->BIR.Header.Type = BioAPI_BIR_DATA_TYPE_RAW;
	pHeadNode->BIR.Header.Format.FormatOwner = LittleEndian2 (BIO_DATA_FORMAT_OWNER);
	pHeadNode->BIR.Header.Format.FormatID	 = LittleEndian2 (BIO_DATA_FORMAT_ID);
	pHeadNode->BIR.Header.Quality			 = 100; /* by definition */
	pHeadNode->BIR.Header.FactorsMask		 = LittleEndian4 (BioAPI_FACTOR_PASSWORD);

	/* The Purpose will be used in the HRS Process function
	 * to make sure that BIRs which are captured for verification
	 * are not hashed; otherwise, they're useless. */
	pHeadNode->BIR.Header.PurposeMask		 = Purpose;

	bioDataHeader.PWLength		   = capturedBIRLength = strlen(inputPassword);
	bioDataHeader.PayloadLength	   = 0;
	pHeadNode->BIR.Header.Length   = LittleEndian4 (sizeof(BioAPI_BIR_HEADER) +
									 sizeof(BIO_DATA_HEADER) + capturedBIRLength);

	/* Finish BIR */
	pHeadNode->BIR.Signature	 = NULL;
	pHeadNode->BIR.BiometricData =
		(BioAPI_BIR_BIOMETRIC_DATA*)
			BioAPI_malloc(capturedBIRLength + sizeof(BIO_DATA_HEADER), NULL);
	port_memcpy((void*)pHeadNode->BIR.BiometricData, (void*)&bioDataHeader,
				sizeof(BIO_DATA_HEADER));
	port_memcpy((void*)(pHeadNode->BIR.BiometricData + sizeof(BIO_DATA_HEADER)),
				inputPassword, capturedBIRLength);

	/* Wipe password out of buffer */
	port_memset((void*)inputPassword, 0, MAX_PASSWORD_SIZE);

	return BioAPI_OK;
}