/* SCCSID: fwk/cssm/free.c, dss_cdsa_fwk, fwk_rel2, dss_971010 1.6 10/10/97 10:48:57 */
/* ***************************************************************** *
 * Copyright 1998 International Business Machines Corporation. All   *
 * Rights Reserved.                                                  *
 *                                                                   *
 * Please read this carefully.  Your use of this reference           *
 * implementation of certain of the IETF public-key infrastructure   *
 * specifications ("Software") indicates your acceptance of the      *
 * following.  If you do not agree to the following, do not install  *
 * or use any of the Software.                                       *
 *                                                                   *
 * Permission to use, reproduce, distribute and create derivative    *
 * works from the Software ("Software Derivative Works"), and to     *
 * distribute such Software Derivative Works is hereby granted to    *
 * you by International Business Machines Corporation ("IBM").  This *
 * permission includes a license under the patents of IBM that are   *
 * necessarily infringed by your use of the Software as provided by  *
 * IBM.                                                              *
 *                                                                   *
 * IBM licenses the Software to you on an "AS IS" basis, without     *
 * warranty of any kind.  IBM HEREBY EXPRESSLY DISCLAIMS ALL         *
 * WARRANTIES OR CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING,   *
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OR CONDITIONS OF       *
 * MERCHANTABILITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR    *
 * PURPOSE.  You are solely responsible for determining the          *
 * appropriateness of using this Software and assume all risks       *
 * associated with the use of this Software, including but not       *
 * limited to the risks of program errors, damage to or loss of      *
 * data, programs or equipment, and unavailability or interruption   *
 * of operations.                                                    *
 *                                                                   *
 * IBM WILL NOT BE LIABLE FOR ANY DIRECT DAMAGES OR FOR ANY SPECIAL, *
 * INCIDENTAL, OR  INDIRECT DAMAGES OR FOR ANY ECONOMIC              *
 * CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS), EVEN   *
 * IF IBM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  IBM  *
 * will not be liable for the loss of, or damage to, your records or *
 * data, or any damages claimed by you based on a third party claim. *
 *                                                                   *
 * IBM wishes to obtain your feedback to assist in improving the     *
 * Software.  You grant IBM a world-wide, royalty-free right to use, *
 * copy, distribute, sublicense and prepare derivative works based   *
 * upon any feedback, including materials, error corrections,        *
 * Software Derivatives, enhancements, suggestions and the like that *
 * you provide to IBM relating to the Software (this does not        *
 * include products for which you charge a royalty and distribute to *
 * IBM under other terms and conditions).                            *
 *                                                                   *
 * You agree to distribute the Software and any Software Derivatives *
 * under a license agreement that: 1) is sufficient to notify all    *
 * licensees of the Software and Software Derivatives that IBM       *
 * assumes no liability for any claim that may arise regarding the   *
 * Software or Software Derivatives, and 2) that disclaims all       *
 * warranties, both express and implied, from IBM regarding the      *
 * Software and Software Derivatives.  (If you include this          *
 * Agreement with any distribution of the Software or Software       *
 * Derivatives you will have met this requirement.)  You agree that  *
 * you will not delete any copyright notices in the Software.        *
 *                                                                   *
 * This Agreement is the exclusive statement of your rights in the   *
 * Software as provided by IBM.   Except for the rights granted to   *
 * you in the second paragraph above, You are not granted any other  *
 * patent rights, including but not limited to the right to make     *
 * combinations of the Software with products that infringe IBM      *
 * patents. You agree to comply with all applicable laws and         *
 * regulations, including all export and import laws and regulation. *
 * This Agreement is governed by the laws of the State of New York.  *
 * This Agreement supersedes all other communications,               *
 * understandings or agreements we may have had prior to this        *
 * Agreement.                                                        *
 * ***************************************************************** */

/*-----------------------------------------------------------------------
 *      File:   free.C
 *
 */
/*
 * (C) COPYRIGHT International Business Machines Corp. 1996, 1997
 * All Rights Reserved
 * Licensed Materials - Property of IBM
 *
 * Copyright (c) 1995, 1996, 1997 Intel Corporation. All rights reserved.
 *
 * US Government Users Restricted Rights - Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *
 */
/*
 * WARNING: EXPORT RESTRICTED.
 * This software listing contains cryptographic methods and technology.
 * It is export restricted by the Office of Defense Trade Controls, United
 * States Department of State and cannot be downloaded or otherwise
 * exported or re-exported (i) into (or to a national or resident of) Cuba,
 * Iraq, Libya, Yugoslavia, North Korea, Iran, Syria or any other country
 * to which the US has embargoed goods; or (ii) to anyone on the US
 * Treasury Department's list of Specially Designated Nationals or the US
 * Commerce Department's Table of Denial Orders. By downloading or using
 * this product, you are agreeing to the foregoing and you are representing
 * and warranting that you are not located in, under the control of, or a
 * national or resident of any such country or on any such list.
 */

#include "cssm.h"
#include "cssmport.h"
#include "internal.h"
#include "addin.h"
#include "context.h"

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeString
 *
 *Description:
 *   Free string that was allocated for an application
 *
 *Parameters:
 *   Str (input) - pointer to the string
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN cssm_FreeString (char *Str)
{

    if (Str == NULL)
       return(CSSM_OK);

    if (IsBadReadPtr (Str, 1)) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

    if (IsBadReadPtr (Str, strlen (Str))) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

    app_free (Str, memRef);
    return(CSSM_OK);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeTPSubService
 *
 *Description:
 *   Free memory associated with the TPINFO structure
 *
 *Parameters:
 *   Info (input) - pointer to TP Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN CSSMAPI cssm_FreeTPSubService (CSSM_TPSUBSERVICE_PTR Sub)
{
    uint32 cnt;

    /* clear the error */

    CSSM_ClearError ();

    if (IsBadReadPtr (Sub, sizeof (CSSM_TPSUBSERVICE))) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

    /* Free PolicyIdentifiers memory */
    for (cnt = 0; cnt < Sub->NumberOfPolicyIdentifiers; cnt++) {
        CSSM_OID_PTR ptr;

        if (IsBadReadPtr (&Sub->PolicyIdentifiers[cnt], sizeof (CSSM_FIELD))) {
            CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
            return(CSSM_FAIL);
        }

        ptr = &Sub->PolicyIdentifiers[cnt].FieldOid;
        if (IsBadReadPtr (ptr->Data, ptr->Length)) {
            CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
            return(CSSM_FAIL);
        }
        app_free (ptr->Data, memRef);

        ptr = &Sub->PolicyIdentifiers[cnt].FieldValue;
        if (IsBadReadPtr (ptr->Data, ptr->Length)) {
            CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
            return(CSSM_FAIL);
        }
        app_free (ptr->Data, memRef);
    }

    /* Free Array of OID memory */
    if (Sub->NumberOfPolicyIdentifiers > 0)
        if (!IsBadReadPtr (Sub->PolicyIdentifiers, sizeof (CSSM_FIELD) * Sub->NumberOfPolicyIdentifiers)) {
            app_free (Sub->PolicyIdentifiers, memRef);
        }

    return(CSSM_OK);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeSWInfo
 *
 *Description:
 *   Free memory associated with the SOFTWARE_SUBSERVICEINFO structure
 *
 *Parameters:
 *   Info (input) - pointer to SOFTWARE Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN cssm_FreeSWInfo (CSSM_SOFTWARE_CSPSUBSERVICE_INFO_PTR Info)
{

    uint32 i;

    /* free the entire capabilities list */

    for (i = 0; i < Info->NumberOfCapabilities; i++)
    {
        CSSM_CSP_CAPABILITY_PTR pCon = &Info->CapabilityList[i];
        cssm_FreeAttributes (pCon->NumberOfAttributes, pCon->ContextAttributes, app_free, memRef, 1);
    }

    /* Free the pointer to capabilities list */
    app_free(Info->CapabilityList, memRef);

    return(CSSM_OK);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeHardwareInfo
 *
 *Description:
 *   Free memory associated with the hradware structure
 *
 *Parameters:
 *   Info (input) - pointer to hradware Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN cssm_FreeHardwareInfo (CSSM_HARDWARE_CSPSUBSERVICE_INFO_PTR Info)
{

    if (!IsBadReadPtr (Info->UserCACertificate.Data, Info->UserCACertificate.Length)) {
        app_free (Info->UserCACertificate.Data, memRef);
    }

    /* free the common info structure */
    if (cssm_FreeSWInfo ((CSSM_SOFTWARE_CSPSUBSERVICE_INFO_PTR)Info) != CSSM_OK)
        return(CSSM_FAIL);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeCSPWrapped
 *
 *Description:
 *   Free memory associated with the CSP_WRAPPEDPRODUCT_INFO structure
 *
 *Parameters:
 *   Info (input) - pointer to CSP_WRAPPEDPRODUCT_INFO Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN cssm_FreeCSPWrapped (CSSM_CSP_WRAPPEDPRODUCT_INFO_PTR Info)
{

    return(CSSM_OK);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeCSPSubService
 *
 *Description:
 *   Free memory associated with the CSPINFO structure
 *
 *Parameters:
 *   Info (input) - pointer to CSP Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN CSSMAPI cssm_FreeCSPSubService (CSSM_CSPSUBSERVICE_PTR Sub)
{
    /* clear the error */

    CSSM_ClearError ();

    if (IsBadReadPtr (Sub, sizeof (CSSM_CSPSUBSERVICE))) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

        if (Sub->CspType == CSSM_CSP_SOFTWARE) {
            if (cssm_FreeSWInfo (&Sub->SoftwareCspSubService) != CSSM_OK)
                return(CSSM_FAIL);
        }
        else if (Sub->CspType == CSSM_CSP_HARDWARE) {
            if (cssm_FreeHardwareInfo (&Sub->HardwareCspSubService) != CSSM_OK)
                return(CSSM_FAIL);
        }

    return(CSSM_OK);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeDBAttributeInfo
 *
 *Description:
 *   Free memory associated with the DB_ATTRIBUTE structure
 *
 *Parameters:
 *   Info (input) - pointer to DB_ATTRIBUTE Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN cssm_FreeDbAttributeInfo(CSSM_DB_ATTRIBUTE_INFO_PTR Info)
{

    if (Info->AttributeNameFormat == CSSM_DB_ATTRIBUTE_NAME_AS_STRING)
    {
        if (Info->AttributeName != NULL)
            app_free(Info->AttributeName, memRef);
    }
    else
    {
        if (Info->AttributeID.Data != NULL)
            app_free(Info->AttributeID.Data, memRef);
    }
    return(CSSM_OK);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeDBInfo
 *
 *Description:
 *   Free memory associated with the DBINFO structure
 *
 *Parameters:
 *   Info (input) - pointer to DB Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN cssm_FreeDbInfo (CSSM_DBINFO_PTR Info)
{
    uint32 i;

    if (IsBadReadPtr (Info->RecordAttributeNames, sizeof (CSSM_DB_RECORD_ATTRIBUTE_INFO)
            * Info->NumberOfRecordTypes)) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

    if (IsBadReadPtr (Info->RecordIndexes, sizeof (CSSM_DB_RECORD_INDEX_INFO)
            * Info->NumberOfRecordTypes)) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

    /* free all record types */
    for (i = 0; i < Info->NumberOfRecordTypes; i++)
    {
        uint32 j;
        if (Info->RecordAttributeNames[i].AttributeInfo)
        {
            if (IsBadReadPtr (Info->RecordAttributeNames[i].AttributeInfo, sizeof
                    (CSSM_DB_ATTRIBUTE_INFO) * Info->RecordAttributeNames[i].NumberOfAttributes)) {
                CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
                return(CSSM_FAIL);
            }

            for (j = 0; j < Info->RecordAttributeNames[i].NumberOfAttributes; j++)
            {
                cssm_FreeDbAttributeInfo(&Info->RecordAttributeNames[i].AttributeInfo[j]);
            }
            app_free(Info->RecordAttributeNames[i].AttributeInfo, memRef);
        }

        if (Info->RecordIndexes[i].IndexInfo)
        {
            if (IsBadReadPtr (Info->RecordIndexes[i].IndexInfo, sizeof
                    (CSSM_DB_INDEX_INFO) * Info->RecordIndexes[i].NumberOfIndexes)) {
                CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
                return(CSSM_FAIL);
            }

            for (j = 0; j < Info->RecordIndexes[i].NumberOfIndexes; j++)
            {
                cssm_FreeDbAttributeInfo(&Info->RecordIndexes[i].IndexInfo[j].Info);
            }

            app_free(Info->RecordIndexes[i].IndexInfo, memRef);

        }
    }

    if (Info->DefaultParsingModules)
        app_free(Info->DefaultParsingModules, memRef);
    if (Info->RecordAttributeNames)
        app_free(Info->RecordAttributeNames, memRef);
    if (Info->RecordIndexes)
        app_free(Info->RecordIndexes, memRef);
    if (Info->SigningCertificate.Data)
        app_free(Info->SigningCertificate.Data, memRef);
    if (Info->AccessPath)
        app_free(Info->AccessPath, memRef);
    if (Info->Reserved && ((CSSM_DATA_PTR)Info->Reserved)->Data)
        app_free(((CSSM_DATA_PTR)Info->Reserved)->Data, memRef);

    return(CSSM_OK);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeDLSubService
 *
 *Description:
 *   Free memory associated with the DLINFO structure
 *
 *Parameters:
 *   Info (input) - pointer to DL Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN CSSMAPI cssm_FreeDLSubService (CSSM_DLSUBSERVICE_PTR Sub)
{
    /* clear the error */

    CSSM_ClearError ();

    /* check to make sure that array is OK */
    if (IsBadReadPtr (Sub, sizeof (CSSM_DLSUBSERVICE))) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

    /* free every sub service */
    switch (Sub->Type) {
        case CSSM_DL_PKCS11 :
            app_free (Sub->Attributes.Pkcs11Attributes, memRef);
        break;
    }

    if (Sub->RelOperatorTypes)
        app_free (Sub->RelOperatorTypes, memRef);
    if (Sub->ConjOperatorTypes)
        app_free (Sub->ConjOperatorTypes, memRef);

    if (Sub->NumberOfDataStores > 0)
    {
        uint32 j;

        if (IsBadReadPtr (Sub->DataStoreInfo, sizeof(CSSM_DBINFO) * Sub->NumberOfDataStores)) {
                CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
                return(CSSM_FAIL);
            }

        if (IsBadReadPtr (Sub->DataStoreNames, sizeof(CSSM_NAME_LIST) * Sub->NumberOfDataStores)) {
            CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
            return(CSSM_FAIL);
        }

        for (j=0; j < Sub->NumberOfDataStores; j++) {
            uint32 k;

            for (k = 0; k < Sub->DataStoreNames[j].NumStrings; k++)
            {
                app_free(Sub->DataStoreNames[j].String[k], memRef);
            }
            app_free(Sub->DataStoreNames[j].String, memRef);

            cssm_FreeDbInfo (&Sub->DataStoreInfo[j]);
        }
        if (Sub->DataStoreNames)
           app_free (Sub->DataStoreNames, memRef);

        if (Sub->DataStoreInfo)
            app_free (Sub->DataStoreInfo, memRef);
    }

    return(CSSM_OK);

}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeCLWrapped
 *
 *Description:
 *   Free memory associated with the CL_WRAPPEDPRODUCT structure
 *
 *Parameters:
 *   Info (input) - pointer to CL_WRAPPEDPRODUCT Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN cssm_FreeCLWrapped(CSSM_CL_WRAPPEDPRODUCT_INFO_PTR Wrapped)
{

    if (Wrapped->NumberOfEncoderProducts > 0)
    {
        if (IsBadReadPtr (Wrapped->EmbeddedEncoderProducts, sizeof (CSSM_CL_ENCODER_PRODUCTINFO)
                * Wrapped->NumberOfEncoderProducts)) {
            CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
            return(CSSM_FAIL);
        }

        app_free(Wrapped->EmbeddedEncoderProducts,memRef);
    }

    if (Wrapped->NumberOfCAProducts > 0)
    {
        CSSM_CL_CA_PRODUCTINFO_PTR CA = Wrapped->AccessibleCAProducts;
        if (IsBadReadPtr(Wrapped->AccessibleCAProducts, sizeof(CSSM_CL_CA_PRODUCTINFO) *
                Wrapped->NumberOfCAProducts)) {
            CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
            return(CSSM_FAIL);
        }

        app_free(Wrapped->AccessibleCAProducts,memRef);
    }
    return(CSSM_OK);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeCLSubService
 *
 *Description:
 *   Free memory associated with the CLINFO structure
 *
 *Parameters:
 *   Info (input) - pointer to CL Info
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN CSSMAPI cssm_FreeCLSubService (CSSM_CLSUBSERVICE_PTR Sub)
{
    uint32 cnt;

    /* clear the error */

    CSSM_ClearError ();

    /* check to make sure that array is OK */
    if (IsBadReadPtr (Sub, sizeof (CSSM_CLSUBSERVICE))) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

    /* free every sub service */
    /* Free certTemplate memory */
    for (cnt = 0; cnt < Sub->NumberOfTemplateFields; cnt++) {
        CSSM_OID_PTR ptr = &Sub->CertTemplates[cnt];

        if (IsBadReadPtr (ptr, sizeof (CSSM_OID))) {
            CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
            return(CSSM_FAIL);
        }

        if (IsBadReadPtr (ptr->Data, ptr->Length)) {
            CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
            return(CSSM_FAIL);
        }

        app_free (ptr->Data, memRef);
     }

    /* Free Array of OID memory */
    if (Sub->NumberOfTemplateFields > 0)
        if (!IsBadReadPtr (Sub->CertTemplates, sizeof (CSSM_OID) * Sub->NumberOfTemplateFields)) {
            app_free (Sub->CertTemplates, memRef);
        }

    /* Free certTranslationTypes memory */
    if (Sub->NumberOfTranslationTypes > 0)
        if (!IsBadReadPtr (Sub->CertTranslationTypes, sizeof (CSSM_CERT_TYPE) * Sub->NumberOfTranslationTypes)) {
            app_free (Sub->CertTranslationTypes, memRef);
        }

    if (cssm_FreeCLWrapped(&Sub->WrappedProduct) != CSSM_OK)
        return(CSSM_FAIL);

    return(CSSM_OK);
}

/*---------------------------------------------------------------
 *
 *Name: cssm_FreeList
 *
 *Description:
 *   Free memory associated with the CSSM_LIST
 *
 *Parameters:
 *   List (input) - pointer to CSSM_LIST pointer
 *
 *Returns:
 *   CSSM_FAIL - unable to free
 *   CSSM_OK - free memory
 *
 *-------------------------------------------------------------*/
CSSM_RETURN CSSMAPI CSSM_FreeList (CSSM_LIST_PTR List)
{
    uint32 i;

    /* clear the error */

    CSSM_ClearError ();

    /* make sure we have a valid list */
    if (IsBadReadPtr (List, sizeof (CSSM_LIST))) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

    /* make sure we have memory for the number of items */
    if (IsBadReadPtr (List->Items, sizeof (CSSM_LIST_ITEM) * List->NumberItems)) {
        CSSM_SetError (&cssm_GUID, CSSM_INVALID_POINTER);
        return(CSSM_FAIL);
    }

    /* delete every entry in list */
    for (i=0; i<List->NumberItems; i++) {
        if (List->Items[i].Name)
            if (!IsBadReadPtr (List->Items[i].Name, strlen (List->Items[i].Name)))
                app_free (List->Items[i].Name, memRef);
    }

    /* free the list itself */
    app_free (List->Items, memRef);
    app_free (List, memRef);

    return(CSSM_OK);
}
