/*----------------------------------------------------------------------- * File: MAF_MISC.C * * Copyright (c) 1995-2000 Intel Corporation. All rights reserved. *----------------------------------------------------------------------- */ /* * OpenVMS History * * 13-Sep-2002 Carol Kelly * o Merge in V3_14 changes * 02-Nov-1999 Carol Kelly * o Merge in changes from Unix code base * */ #include "maf_include.h" static const char FileURLHdr[] = "file://"; CSSM_RETURN MAF_CreateOutputBuffer( CSSM_MODULE_HANDLE ModuleHandle, uint32 uRequiredSize, CSSM_DATA *pOutBuffer, CSSM_BOOL *pbAllocated ) { assert( pOutBuffer && pbAllocated ); /* Are we allocating the memory or checking data length? */ if ( pOutBuffer->Data == NULL ) { /* We need to allocate the memory */ pOutBuffer->Data = MAF_MALLOC( ModuleHandle, uRequiredSize ); if ( pOutBuffer->Data == NULL ) { return ERR( CSSMERR_CSP_MEMORY_ERROR ); } /* Set the buffer length */ pOutBuffer->Length = uRequiredSize; /* Indicate that we allocated the memory */ *pbAllocated = CSSM_TRUE; } else { /* The memory is allocated, check for required length */ if ( pOutBuffer->Length < uRequiredSize ) { return ERR( CSSMERR_CSP_OUTPUT_LENGTH_ERROR ); } /* Indicate the we did not allocate the memory */ *pbAllocated = CSSM_FALSE; } return CSSM_OK; } CSSM_RETURN MAF_DeleteOutputBuffer( CSSM_MODULE_HANDLE ModuleHandle, CSSM_DATA *pOutBuffer, CSSM_BOOL bAllocated ) { if ( ( bAllocated == CSSM_TRUE ) && ( pOutBuffer ) && ( pOutBuffer->Data != NULL ) ) { /* Do we deallocate locally or from the caller */ MAF_FREE( ModuleHandle, pOutBuffer->Data ); /* Clear the buffer values */ pOutBuffer->Data = NULL; pOutBuffer->Length = 0; } return CSSM_OK; } /**------------------------------------------------------------------------- ** MAF_GetPrintableGUID ** ** Description ** Formats a CSSM_GUID structure into a printable format. The output ** matches the format used by the Win32 registry. ** ** Parameters ** pGUID (input) - The CSSM_GUID structure to convert. ** PrintableGUID (output) - Pointer to a character buffer with enough ** space for at least MAF_PRINTABLE_GUID_LENGTH characters. ** ** Return Value ** CSSM_INVALID_POINTER - The memory referenced by the pGUID pointer is ** unreadable or the PrintableGUID parameter is not writable. ** CSSM_OK - The GUID has been converted. *-------------------------------------------------------------------------- **/ CSSM_RETURN MAF_GetPrintableGUID( const CSSM_GUID *pGUID, char *PrintableGUID ) { /* Parameter checks */ if ( port_IsBadReadPtr( pGUID, sizeof(CSSM_GUID) ) || port_IsBadWritePtr( PrintableGUID, MAF_PRINTABLE_GUID_LENGTH ) ) { return CSSM_ERRCODE_INVALID_INPUT_POINTER; } /* Format the output */ sprintf( PrintableGUID, GUID_FORMAT_STRING, pGUID->Data1, pGUID->Data2, pGUID->Data3, pGUID->Data4[0], pGUID->Data4[1], pGUID->Data4[2], pGUID->Data4[3], pGUID->Data4[4], pGUID->Data4[5], pGUID->Data4[6], pGUID->Data4[7] ); return CSSM_OK; } CSSM_RETURN MAF_GetStructuredGUID( const char *PrintableGUID, CSSM_GUID *pGUID ) { int nCount; uint32 i, Data1; uint32 Data2, Data3; uint32 Data4[8]; /* Parameter checks */ if ( ( port_IsBadWritePtr( pGUID, sizeof(CSSM_GUID) ) != CSSM_OK ) || ( port_IsBadReadPtr( PrintableGUID, MAF_PRINTABLE_GUID_LENGTH ) != CSSM_OK ) ) { return CSSM_ERRCODE_INVALID_POINTER; } /* Format the output */ nCount = sscanf( PrintableGUID, GUID_FORMAT_STRING, #ifdef COMPAQ_FIX &Data1, &Data2, &Data3, &Data4[0], &Data4[1], &Data4[2], &Data4[3], &Data4[4], &Data4[5], &Data4[6], &Data4[7] ); #else /* COMPAQ_FIX */ &Data1, &Data2, &Data3, &Data4[0], &Data4[1], &Data4[2], &Data4[3], &Data4[4], &Data4[5], &Data4[6], &Data4[7] ); #endif /* COMPAQ_FIX */ if ( nCount != 11 ) { return CSSMERR_CSP_INVALID_DATA; } pGUID->Data1 = Data1; pGUID->Data2 = (uint16) Data2; pGUID->Data3 = (uint16) Data3; for ( i = 0; i < 8; i++ ) pGUID->Data4[i] = (uint8) Data4[i]; return CSSM_OK; } CSSM_RETURN MAF_GetPrintableVersion( const CSSM_VERSION *pVersion, char *PrintableVersion ) { /* Parameter check */ if ( ( pVersion == NULL ) || ( PrintableVersion == NULL ) ) { return CSSM_ERRCODE_INVALID_POINTER; } /* format the output */ sprintf( PrintableVersion, "%d.%d", pVersion->Major, pVersion->Minor ); return CSSM_OK; } CSSM_RETURN MAF_GetStructuredVersion( const char *PrintableVersion, CSSM_VERSION *pVersion ) { int nCount; /* Parameter check */ if ( ( pVersion == NULL ) || ( PrintableVersion == NULL ) ) { return CSSM_ERRCODE_INVALID_POINTER; } /* format the output */ nCount = sscanf( PrintableVersion, "%d.%d", &pVersion->Major, &pVersion->Minor ); return CSSM_OK; } /**------------------------------------------------------------------------- ** MAF_SystemPath2FileURL ** ** Description ** Formats an operating system path into a file URL. Path separators and ** drive specifiers are changed depending on the OS. ** ** Parameters ** SystemPath (input) - System path to convert. ** FileURL (output) - Converted system path. ** ** Return Value ** CSSM_INVALID_POINTER - Any of the parameters are NULL. ** CSSM_OK - The system path has been converted. *-------------------------------------------------------------------------- **/ CSSM_RETURN MAF_SystemPath2FileURL( const char *SystemPath, char *FileURL ) { int Index = 0; /* Parameter Check */ if ( ( FileURL == NULL ) || ( SystemPath == NULL ) ) { return CSSM_ERRCODE_INVALID_POINTER; } /* Add the URL header to the output */ strcpy( FileURL, FileURLHdr ); #ifdef WIN32 strcat( FileURL, "/" ); /* Microsoft paths have a leading slash before * the drive letter. */ #endif /* Add the path to the URL */ strcat( FileURL, SystemPath ); #ifdef WIN32 /* Convert the Microsoft path to an URL path */ Index = strlen( FileURLHdr ); for ( ; FileURL[Index]; Index++ ) { if ( FileURL[Index] == '\\' ) { FileURL[Index] = '/'; } else if ( FileURL[Index] == ':' ) { FileURL[Index] = '|'; } } #endif return CSSM_OK; } #if 0 /**------------------------------------------------------------------------- ** MAF_FileURL2SystemPath ** ** Description ** Converts a file URL to a system path. Checks are made to insure a ** properly formatted URL header. Path separators and drive specifiers are ** changed based on the OS. ** ** Parameters ** FileURL (input) - File URL to convert. ** SystemPath (output) - Converted system path. ** ** Return Value ** CSSM_INVALID_POINTER - Any of the parameters are NULL. ** CSSM_OK - The system path has been converted. *-------------------------------------------------------------------------- **/ CSSM_RETURN MAF_FileURL2SystemPath( const char *FileURL, char *SystemPath ) { int Index = 0; /* Parameter Check */ if ( ( FileURL == NULL ) || ( SystemPath == NULL ) ) { return CSSM_INVALID_POINTER; } /* Is this really a file URL? */ if ( strnicmp( FileURL, FileURLHdr, strlen( FileURLHdr ) ) != 0 ) { return MAFR_INVALID_PATH; } /* Confirm that the next character is a '/' */ Index = strlen(FileURLHdr); if ( FileURL[Index] != '/' ) { return MAFR_INVALID_PATH; } #ifdef WIN32 /* Skip past the first slash on Win32 systems. The slash before the * drive letter is discarded. */ Index++; #endif /* Copy the new path */ strcpy( SystemPath, &FileURL[Index] ); #ifdef WIN32 /* Convert the URL path to the Microsoft format */ for ( ; SystemPath[Index]; Index++ ) { if ( SystemPath[Index] == '/' ) { SystemPath[Index] = '\\'; } else if ( SystemPath[Index] == '|') { SystemPath[Index] = ':'; } else { SystemPath[Index] = FileURL[Index]; } } #endif return CSSM_OK; } #endif CSSM_RETURN MAF_ResolveCryptoData( const CSSM_CRYPTO_DATA *pCryptoData, CSSM_DATA *pResolvedData, uint32 uMaxLength, CSSM_BOOL *pbAllocated ) { CSSM_RETURN rv = 0; CSSM_DATA DataBuffer = { 0, NULL }; assert( pResolvedData && pbAllocated ); *pbAllocated = CSSM_FALSE; /* Allocate the space for the data buffer if necessary */ if ( pCryptoData == NULL ) { ERR( rv = CSSMERR_CSP_INVALID_CRYPTO_DATA ); } else if ( ( pCryptoData->Param.Data == NULL ) && ( pCryptoData->Callback == NULL ) ) { ERR( rv = CSSMERR_CSP_INVALID_CRYPTO_DATA ); } else if ( ( pResolvedData->Data != NULL ) && ( pResolvedData->Length < uMaxLength ) ) { ERR( rv = CSSMERR_CSP_INPUT_LENGTH_ERROR ); } else if ( pResolvedData->Data != NULL ) { DataBuffer = *pResolvedData; } else { DataBuffer.Data = Addin_malloc( uMaxLength, NULL ); if ( DataBuffer.Data == NULL ) { ERR( rv = CSSM_ERRCODE_MEMORY_ERROR ); } else { DataBuffer.Length = uMaxLength; *pbAllocated = CSSM_TRUE; } } if ( rv == CSSM_OK ) { /* Is the data in the structure or do we call the callback function */ if ( pCryptoData->Param.Data != NULL ) { /* The data is in the structure */ DataBuffer.Length = min( pCryptoData->Param.Length, uMaxLength ); memcpy( DataBuffer.Data, pCryptoData->Param.Data, DataBuffer.Length ); } else if ( pCryptoData->Callback != NULL ) { /* The data must be fetched from the callback */ rv = pCryptoData->Callback( &DataBuffer, pCryptoData->CallerCtx ); } else { /* Nothing to fetch. */ /* Return an empty structure. In this case the * structure is emptied by setting the result length to zero, if * the caller passed a buffer or freeing the buffer and setting * the length to zero and the buffer to NULL if the buffer was * allocated by the function. */ ERR( rv = CSSM_ERRCODE_INTERNAL_ERROR ); } if ( rv == CSSM_OK ) { /* Limit the output length to the specified maximum length */ DataBuffer.Length = min( uMaxLength, DataBuffer.Length ); /* Set the return value */ *pResolvedData = DataBuffer; } else { if ( pResolvedData->Data == NULL ) { /* We allocated the buffer */ memset( DataBuffer.Data, 0, DataBuffer.Length ); Addin_free( DataBuffer.Data, NULL ); } } } return rv; }