/*----------------------------------------------------------------------- * File: CSM_CNTX.C * * Copyright (c) 1995-2000 Intel Corporation. All rights reserved. *----------------------------------------------------------------------- */ #include "maf_include.h" #ifdef VMS #include "cssmutil.h" #else #include "util/cssmutil.h" #endif const CSSM_CONTEXT_ATTRIBUTE* CSM_GetContextAttribute( const CSSM_CONTEXT *pContext, CSSM_ATTRIBUTE_TYPE AttributeType ) { uint32 Index; /* Do we have something to search? */ if ( pContext == NULL ) { return NULL; } if ( pContext->ContextAttributes == NULL ) { return NULL; } /* Search the attribute list for AttributeType */ for ( Index = 0; Index < pContext->NumberOfAttributes; Index++ ) { if ( pContext->ContextAttributes[Index].AttributeType == AttributeType ) { return &pContext->ContextAttributes[Index]; } } return NULL; } CSSM_RETURN CSM_FreeContextAttributes( CSSM_CONTEXT_ATTRIBUTE *pAttributes, uint32 uNumAttributes ) { CSSM_RETURN mrReturn = CSSM_OK; uint32 Index; CSSM_CONTEXT_ATTRIBUTE *pAttribute = NULL; /* Is there something to deallocate? */ if ( pAttributes == NULL ) { return CSSM_OK; } /* Free attributes */ for ( Index = 0; Index < uNumAttributes; Index++) { pAttribute = &pAttributes[Index]; switch ( pAttribute->AttributeType & CSSM_ATTRIBUTE_TYPE_MASK ) { case CSSM_ATTRIBUTE_DATA_NONE: case CSSM_ATTRIBUTE_DATA_UINT32: break; case CSSM_ATTRIBUTE_DATA_CSSM_DATA: { /* Is the CSSM_DATA there? */ if ( pAttribute->Attribute.Data != NULL ) { /* Does the structure contain data? */ if ( pAttribute->Attribute.Data->Data ) { /* Wipe the data in the structure */ memset( pAttribute->Attribute.Data->Data, 0, pAttribute->Attribute.Data->Length ); /* Free the data in the structure */ Addin_free( pAttribute->Attribute.Data->Data, NULL ); } /* Wipe the CSSM_DATA */ memset( pAttribute->Attribute.Data, 0, sizeof(CSSM_DATA) ); /* Free the CSSM_DATA */ Addin_free( pAttribute->Attribute.Data, NULL ); } break; } case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA: { /* Is the CSSM_CRYPTO_DATA there? */ if ( pAttribute->Attribute.CryptoData ) { /* Does the structure contain parameter data? */ if ( pAttribute->Attribute.CryptoData->Param.Data ) { /* Wipe the data in the structure */ memset( pAttribute->Attribute.CryptoData->Param.Data, 0, pAttribute->Attribute.CryptoData->Param.Length ); /* Free the data in the structure */ Addin_free( pAttribute->Attribute.CryptoData->Param.Data, NULL ); } /* Wipe the CSSM_CRYPTO_DATA */ memset( pAttribute->Attribute.CryptoData, 0, sizeof(CSSM_CRYPTO_DATA) ); /* Free the CSSM_CRYPTO_DATA */ Addin_free( pAttribute->Attribute.CryptoData, NULL ); } break; } case CSSM_ATTRIBUTE_DATA_KEY: { /* Is the CSSM_KEY there? */ if ( pAttribute->Attribute.Key != NULL ) { /* Does the key have key material? */ if ( pAttribute->Attribute.Key->KeyData.Data != NULL ) { /* Wipe the key material */ memset( pAttribute->Attribute.Key->KeyData.Data, 0, pAttribute->Attribute.Key->KeyData.Length ); /* Free the data in the structure */ Addin_free( pAttribute->Attribute.Key->KeyData.Data, NULL ); } /* Wipe the CSSM_KEY */ memset( pAttribute->Attribute.Key, 0, sizeof(CSSM_KEY) ); /* Free the CSSM_KEY */ Addin_free( pAttribute->Attribute.Key, NULL ); } break; } case CSSM_ATTRIBUTE_DATA_STRING: case CSSM_ATTRIBUTE_DATA_DATE: case CSSM_ATTRIBUTE_DATA_RANGE: case CSSM_ATTRIBUTE_DATA_VERSION: case CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE: { /* Treat all flat structures like strings */ /* Is the string actually there? */ if ( pAttribute->Attribute.String != NULL ) { /* Wipe the string value */ memset( pAttribute->Attribute.String, 0, pAttribute->AttributeLength ); /* Free the string buffer */ Addin_free( pAttribute->Attribute.String, NULL ); } break; } case CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS: { /* Is the CSSM_ACCESS_CREDENTIAL there? */ if ( pAttribute->Attribute.AccessCredentials != NULL ) { /* Free the internal structures */ cssmutil_CleanCertGroup( &pAttribute-> Attribute.AccessCredentials-> BaseCerts.Certs, _Addin_free, NULL ); cssmutil_FreeCSSMSamples( pAttribute-> Attribute.AccessCredentials-> Samples.NumberOfSamples, (CSSM_SAMPLE**)&pAttribute-> Attribute.AccessCredentials-> Samples.Samples, _Addin_free, NULL ); /* Wipe the CSSM_ACCESS_CREDENTIAL */ memset( pAttribute->Attribute.AccessCredentials, 0, sizeof(CSSM_ACCESS_CREDENTIALS) ); /* Free the CSSM_ACCESS_CREDENTIAL */ Addin_free( pAttribute->Attribute.AccessCredentials, NULL ); } break; } default: { /* The duplication function doesn't copy attribute types * that don't match one of the above cases. Something went * wrong. */ mrReturn = CSSMERR_CSP_INTERNAL_ERROR; } } } /* Wipe the attribute array */ memset( pAttributes, 0, sizeof(CSSM_CONTEXT_ATTRIBUTE) * uNumAttributes ); /* Free the attribute array */ Addin_free( pAttributes, NULL ); return mrReturn; } CSSM_RETURN CSM_FreeContext( CSSM_CONTEXT *pContext ) { /* Is there something to delete? */ if ( pContext == NULL ) { return CSSM_OK; } /* Free all the attributes in the context */ CSM_FreeContextAttributes( pContext->ContextAttributes, pContext->NumberOfAttributes ); /* Free context structure */ memset( pContext, 0, sizeof(CSSM_CONTEXT) ); Addin_free( pContext, NULL ); return CSSM_OK; } CSSM_ACCESS_CREDENTIALS* CSM_DuplicateAccessCredentialss( const CSSM_ACCESS_CREDENTIALS *pSrc ) { CSSM_ACCESS_CREDENTIALS *pTempCred = NULL; CSSM_RETURN rv = CSSM_OK; pTempCred = Addin_calloc( 1, sizeof(CSSM_ACCESS_CREDENTIALS), NULL ); if ( pTempCred != NULL ) { /* Copy the structure */ memcpy( pTempCred, pSrc, sizeof(*pTempCred) ); /* Copy the cert group */ if ( ( rv = cssmutil_DuplicateBaseCerts( &pSrc->BaseCerts, _Addin_malloc, _Addin_free, NULL, &pTempCred->BaseCerts ) ) == CSSM_OK ) { /* Copy the samples */ if ( ( rv = cssmutil_DuplicateSampleGroup( &pSrc->Samples, _Addin_malloc, _Addin_free, NULL, &pTempCred->Samples ) ) != CSSM_OK ) { cssmutil_CleanCertGroup( &pTempCred->BaseCerts.Certs, _Addin_free, NULL ); } } if ( rv != CSSM_OK ) { Addin_free( pTempCred, NULL ); pTempCred = NULL; } } return pTempCred; } CSSM_DATA* CSM_DuplicateData( const CSSM_DATA *pData ) { CSSM_DATA *pNewData = NULL; /* Parameter check */ if ( pData == NULL ) { return NULL; } /* Allocate the CSSM_DATA structure */ pNewData = Addin_malloc( sizeof(CSSM_DATA), NULL ); if ( pNewData == NULL ) { return NULL; } /* copy the structure contents */ pNewData->Length = pData->Length; if ( pData->Length == 0 ) { /* Zero length buffer */ pNewData->Data = NULL; } else { /* Allocate the buffer for the data */ pNewData->Data = Addin_malloc( pNewData->Length, NULL ); if ( pNewData->Data == NULL ) { Addin_free( pNewData, NULL ); return NULL; } /* Copy the data */ memcpy( pNewData->Data, pData->Data, pNewData->Length ); } return pNewData; } CSSM_CRYPTO_DATA* CSM_DuplicateCryptoData( const CSSM_CRYPTO_DATA *pCryptoData ) { CSSM_CRYPTO_DATA *pNewCryptoData = NULL; /* Parameter check */ if ( pCryptoData == NULL ) { return NULL; } /* Allocate the CSSM_DATA structure */ pNewCryptoData = Addin_malloc( sizeof(CSSM_CRYPTO_DATA), NULL ); if ( pNewCryptoData == NULL ) { return NULL; } /* copy the structure contents */ pNewCryptoData->Callback = pCryptoData->Callback; pNewCryptoData->CallerCtx = pCryptoData->CallerCtx; pNewCryptoData->Param.Length = pCryptoData->Param.Length; if ( pCryptoData->Param.Length == 0 ) { /* Zero length buffer */ pNewCryptoData->Param.Data = NULL; } else { /* Allocate the buffer for the data */ pNewCryptoData->Param.Data = Addin_malloc( pNewCryptoData->Param.Length, NULL ); if ( pNewCryptoData->Param.Data == NULL ) { Addin_free( pNewCryptoData, NULL ); return NULL; } /* Copy the data */ memcpy( pNewCryptoData->Param.Data, pCryptoData->Param.Data, pNewCryptoData->Param.Length ); } return pNewCryptoData; } CSSM_KEY* CSM_DuplicateKey( const CSSM_KEY *pKey ) { CSSM_KEY *pNewKey = NULL; /* Parameter check */ if ( pKey == NULL ) { return NULL; } /* Allocate the CSSM_DATA structure */ pNewKey = Addin_malloc( sizeof(CSSM_KEY), NULL ); if ( pNewKey == NULL ) { return NULL; } memcpy( pNewKey, pKey, sizeof(CSSM_KEY) ); /* copy the structure contents */ pNewKey->KeyData.Length = pKey->KeyData.Length; if ( pKey->KeyData.Length == 0 ) { /* Zero length buffer */ pNewKey->KeyData.Data = NULL; } else { /* Allocate the buffer for the data */ pNewKey->KeyData.Data = Addin_malloc( pNewKey->KeyData.Length, NULL ); if ( pNewKey->KeyData.Data == NULL ) { /* Wipe the new key and free it */ memset( pNewKey, 0, sizeof(CSSM_KEY) ); Addin_free( pNewKey, NULL ); return NULL; } /* Copy the data */ memcpy( pNewKey->KeyData.Data, pKey->KeyData.Data, pNewKey->KeyData.Length ); } return pNewKey; } uint8* CSM_DuplicateBuffer( const uint8 *pBuffer, uint32 uBufferLen ) { uint8 *pNewBuffer = NULL; /* Parameter check */ if ( ( pBuffer == NULL ) || ( uBufferLen == 0 ) ) { return NULL; } /* Allocate the CSSM_DATA structure */ pNewBuffer = Addin_malloc( sizeof(uint8) * uBufferLen, NULL ); if ( pNewBuffer == NULL ) { return NULL; } memcpy( pNewBuffer, pBuffer, sizeof(uint8) * uBufferLen ); return pNewBuffer; } CSSM_RETURN CSM_DuplicateContextAttributes( const CSSM_CONTEXT_ATTRIBUTE *pAttrSrc, uint32 uNumAttributes, CSSM_CONTEXT_ATTRIBUTE **ppAttrDest ) { CSSM_CONTEXT_ATTRIBUTE *pAttrDest = NULL; const CSSM_CONTEXT_ATTRIBUTE *pSrc = NULL; CSSM_CONTEXT_ATTRIBUTE *pDest = NULL; uint32 Index; /* Parameter check */ if ( ( pAttrSrc == NULL ) && ( uNumAttributes == 0 ) ) { return CSSM_OK; } else if ( pAttrSrc == NULL ) { return CSSMERR_CSP_INVALID_INPUT_POINTER; } if ( ppAttrDest == NULL ) { return CSSMERR_CSP_INVALID_OUTPUT_POINTER; } /* Allocate the attribute buffer */ pAttrDest = Addin_calloc( uNumAttributes, sizeof(CSSM_CONTEXT_ATTRIBUTE), NULL ); if ( pAttrDest == NULL ) { *ppAttrDest = NULL; return CSSMERR_CSP_MEMORY_ERROR; } /* Duplicate each attribute in turn */ for ( Index = 0; Index < uNumAttributes; Index++ ) { pSrc = &pAttrSrc[Index]; pDest = &pAttrDest[Index]; /* Copy the standard attributes */ pDest->AttributeType = pSrc->AttributeType; pDest->AttributeLength = pSrc->AttributeLength; /* Copy the attribute content */ switch ( pSrc->AttributeType & CSSM_ATTRIBUTE_TYPE_MASK ) { case CSSM_ATTRIBUTE_NONE: { /* Nothing to copy */ break; } case CSSM_ATTRIBUTE_DATA_UINT32: { /* The value is stored directly in the structure */ pDest->Attribute.Uint32 = pSrc->Attribute.Uint32; break; } case CSSM_ATTRIBUTE_DATA_CSSM_DATA: { /* Duplicate the CSSM_DATA structure */ pDest->Attribute.Data = CSM_DuplicateData( pSrc->Attribute.Data ); /* Delete the new structure if the duplication failed */ if ( pDest->Attribute.Data == NULL ) { CSM_FreeContextAttributes( pAttrDest, Index ); *ppAttrDest = NULL; return CSSMERR_CSP_MEMORY_ERROR; } break; } case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA: { /* Duplicate the CSSM_CRYPTO_DATA structure */ pDest->Attribute.CryptoData = CSM_DuplicateCryptoData( pSrc->Attribute.CryptoData ); /* Delete the new structure if the duplication failed */ if ( pDest->Attribute.CryptoData == NULL ) { CSM_FreeContextAttributes( pAttrDest, Index ); *ppAttrDest = NULL; return CSSMERR_CSP_MEMORY_ERROR; } break; } case CSSM_ATTRIBUTE_DATA_KEY: { /* Duplicate the CSSM_KEY structure */ pDest->Attribute.Key = CSM_DuplicateKey( pSrc->Attribute.Key ); /* Delete the new structure if the duplication failed */ if ( pDest->Attribute.Key == NULL ) { CSM_FreeContextAttributes( pAttrDest, Index ); *ppAttrDest = NULL; return CSSMERR_CSP_MEMORY_ERROR; } break; } case CSSM_ATTRIBUTE_DATA_STRING: case CSSM_ATTRIBUTE_DATA_DATE: case CSSM_ATTRIBUTE_DATA_RANGE: case CSSM_ATTRIBUTE_DATA_VERSION: case CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE: { /* Duplicate the buffer. Treat all "flat" structures as * strings. */ pDest->Attribute.String = (char *)CSM_DuplicateBuffer( (uint8*)pSrc->Attribute.String, pSrc->AttributeLength ); /* Delete the new structure if the duplication failed */ if ( pDest->Attribute.String == NULL ) { CSM_FreeContextAttributes( pAttrDest, Index ); *ppAttrDest = NULL; return CSSMERR_CSP_MEMORY_ERROR; } break; } case CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS: { /* Duplicate the CSSM_ACCESS_CREDENTIALS structure */ pDest->Attribute.AccessCredentials = CSM_DuplicateAccessCredentialss( pSrc->Attribute.AccessCredentials ); /* Delete the new structure if the duplication failed */ if ( pDest->Attribute.AccessCredentials == NULL ) { CSM_FreeContextAttributes( pAttrDest, Index ); *ppAttrDest = NULL; return CSSMERR_CSP_MEMORY_ERROR; } break; } default: { /* Don't copy the unknown attribute type */ pDest->AttributeType = CSSM_ATTRIBUTE_NONE; pDest->AttributeLength = 0; break; } } /* End select */ } /* End for */ /* Set the return parameters */ *ppAttrDest = pAttrDest; return CSSM_OK; } CSSM_RETURN CSM_DuplicateContext( const CSSM_CONTEXT *pSrcContext, CSSM_CONTEXT **ppDestContext ) { CSSM_CONTEXT *pDestContext = NULL; /* Parameter check */ if ( ( pSrcContext == NULL ) || ( ppDestContext == NULL ) ) { return CSSMERR_CSP_INVALID_POINTER; } /* Allocate the new context */ pDestContext = Addin_malloc( sizeof(CSSM_CONTEXT), NULL ); if ( pDestContext == NULL ) { *ppDestContext = NULL; return CSSMERR_CSP_MEMORY_ERROR; } /* Fill in the context values */ memcpy( pDestContext, pSrcContext, sizeof(CSSM_CONTEXT) ); /* Copy the context attributes */ if ( CSM_DuplicateContextAttributes( pSrcContext->ContextAttributes, pSrcContext->NumberOfAttributes, &pDestContext->ContextAttributes ) != CSSM_OK ) { *ppDestContext = NULL; return CSSMERR_CSP_MEMORY_ERROR; } /* Set the return parameters */ *ppDestContext = pDestContext; return CSSM_OK; }