/* ***************************************************************** *
 * 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.                                                        *
 * ***************************************************************** */

//------------------------------------------------------------
// includes
//------------------------------------------------------------

#ifndef CDSA_12
#define CDSA_12
#endif
#include "jdl.h"
#include "ldapdl.h"


//------------------------------------------------------------
// globals
//------------------------------------------------------------

CSSM_MEMORY_FUNCS gMemoryFuncs;


//------------------------------------------------------------
// private interfaces
//------------------------------------------------------------

static
void* DefaultMalloc(uint32 size);

static
void  DefaultFree(void* memPtr);

static
void* DefaultRealloc(void* memPtr, uint32 size);

static
void* DefaultCalloc(uint32 num, uint32 size);

static
uint32 convertNameToString(asn_x500name& name, char*& nameString);

static
const char* lookupAttributeName(JDL_AttributeType attributeType);

static 
bool matchingAttributeName(JDL_AttributeType attributeType, 
                           const char* attributeName);

                  
//**********************************************************************
//
// Directory Initialization APIs
//
//**********************************************************************


//------------------------------------------------------------
// function: JDL_Initialize
//------------------------------------------------------------

uint32
JDL_Initialize(CSSM_MEMORY_FUNCS& memoryFuncs)
{
   CSSM_VERSION version = { CSSM_MAJOR, CSSM_MINOR };

   gMemoryFuncs = memoryFuncs;

   if (CSSM_FAIL == CSSM_Init(&version, &memoryFuncs, NULL))
      return CSSM_GetError()->error;

   return 0;
}


//------------------------------------------------------------
// function: JDL_Attach
//------------------------------------------------------------

uint32
JDL_Attach(const CSSM_GUID& dataSourceGuid, 
           CSSM_DL_HANDLE& dlHandle)
{
   // there may be multiple DL installed; load only specified GUID

   CSSM_MODULE_INFO* moduleInfoPtr;

   moduleInfoPtr = CSSM_GetModuleInfo((CSSM_GUID*)&dataSourceGuid,
                                      CSSM_SERVICE_DL,
                                      CSSM_ALL_SUBSERVICES,
                                      CSSM_INFO_LEVEL_ALL_ATTR);
   if (!moduleInfoPtr)
       return CSSM_GetError()->error;

   dlHandle = CSSM_ModuleAttach((CSSM_GUID*)&dataSourceGuid,
                                 &moduleInfoPtr->Version,
                                 &gMemoryFuncs,
                                 0,
                                 0,
                                 0,
                                 NULL,
                                 NULL);
   if (!dlHandle)
      return CSSM_GetError()->error;

   if (CSSM_FreeModuleInfo(moduleInfoPtr) == CSSM_FAIL)
       return CSSM_GetError()->error;

   return 0;
}


//------------------------------------------------------------
// function: JDL_OpenDatabase
//------------------------------------------------------------

uint32
JDL_OpenDatabase(const char* dbName,
                 const char* authName,
                 const char* authPassword,
                 CSSM_DL_DB_HANDLE& dataSource)
{
   uint32 status = 0;

   CSSM_DB_ACCESS_TYPE accessRequest = { CSSM_TRUE,     // ReadAccess
                                         CSSM_TRUE,     // WriteAccess
                                         CSSM_FALSE,    // PrivilegedMode
                                         CSSM_FALSE  }; // Asynchronous

   //------------------------------------------------------------
   // fill in LDAP DL authentication information:
   // necessary only if user is supplying a name and password
   //------------------------------------------------------------

   LDAP_BIND_PARMS bindParms;
   CSSM_USER_AUTHENTICATION userAuthentication = {0,0};
   CSSM_DATA userCredential = {0,0};
   CSSM_USER_AUTHENTICATION_PTR userAuthenticationPtr = 0;

   if (authName && authPassword)
   {
      //------------------------------------------------------------
      // fill in LDAP DL specific data structure: LDAP_BIND_PARMS
      //------------------------------------------------------------

      bindParms.DN = (char*)authName;
      bindParms.SASL = 0;
      bindParms.credentials.Data = (unsigned char *) authPassword;
      bindParms.credentials.Length = strlen(authPassword)+1;
      bindParms.rebindproc = (int (__cdecl *)(void)) 0;

		userCredential.Length = sizeof(LDAP_BIND_PARMS);
		userCredential.Data   = (unsigned char*)&bindParms;

      userAuthentication.Credential = &userCredential;

      userAuthenticationPtr = &userAuthentication;
   }

   //------------------------------------------------------------
   // Open LDAP DL Database
   //------------------------------------------------------------

   dataSource.DBHandle = CSSM_DL_DbOpen(dataSource.DLHandle,
                                        dbName,
                                        &accessRequest,
                                        userAuthenticationPtr,
                                        (void *)0);
   if (!dataSource.DBHandle)
   {
      return CSSM_GetError()->error;
   }

   return status;
}


//------------------------------------------------------------
// function: JDL_CloseDatabase
//------------------------------------------------------------

uint32
JDL_CloseDatabase(CSSM_DL_DB_HANDLE& dataSource)
{
   if (CSSM_OK != CSSM_DL_DbClose(dataSource))
   {
      return CSSM_GetError()->error;
   }
   return 0;
}


//**********************************************************************
//
// Directory Publish APIs
//
//**********************************************************************


//------------------------------------------------------------
// function: JDL_PublishAttribute
//------------------------------------------------------------

uint32
JDL_PublishAttribute(CSSM_DL_DB_HANDLE dataSource,
                     asn_x500name& directoryEntry, 
                     asn_object& attribute,
                     JDL_AttributeType attributeType,
                     JDL_Modify replaceOption)
{
   uint32 status = 0;

   buffer_t encoding;
   if ((status = attribute.write(encoding)) != 0)
      return status;

   CSSM_DATA attributeValue;
   attributeValue.Data = encoding.data;
   attributeValue.Length = encoding.data_len;

   if ((status = JDL_ModifyAttribute(dataSource,
                                     directoryEntry, 
                                     attributeType,
                                     attributeValue)) != 0)
      return status;

   return status;
}


//------------------------------------------------------------
// function: JDL_ModifyAttribute
//------------------------------------------------------------

uint32 
JDL_ModifyAttribute(CSSM_DL_DB_HANDLE dataSource,
                    asn_x500name& directoryEntry, 
                    JDL_AttributeType attributeType,
                    CSSM_DATA& attributeValue)
{
   uint32 status = 0;

   //------------------------------------------------------------
   // Convert ASN name to LDAP RFC1485 string
   //------------------------------------------------------------

   char* distinguishedName = 0;
   if ((status = convertNameToString(directoryEntry, distinguishedName)) != 0)
      return status;
      
   //------------------------------------------------------------
   // Create DL Unique Record
   //------------------------------------------------------------

   CSSM_DB_UNIQUE_RECORD_PTR uniqueRecordPtr = 0;
   CSSM_DB_UNIQUE_RECORD uniqueRecordID;

   uniqueRecordID.RecordIdentifier.Length = strlen(distinguishedName) + 1;
   uniqueRecordID.RecordIdentifier.Data = (unsigned char *) distinguishedName;
   uniqueRecordPtr = &uniqueRecordID;

   //------------------------------------------------------------
   // Create single attribute data
   //------------------------------------------------------------

   CSSM_DB_ATTRIBUTE_DATA attributeData;
   attributeData.Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; 
   attributeData.Info.AttributeName       = (char*)lookupAttributeName(attributeType);
   attributeData.Value                    = attributeValue;

   CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttributeData;
   recordAttributeData.DataRecordType      = CSSM_DL_DB_RECORD_GENERIC;
   recordAttributeData.SemanticInformation = 0; 
   recordAttributeData.NumberOfAttributes  = 1;  
   recordAttributeData.AttributeData       = &attributeData;

   CSSM_BOOL result;

   result = CSSM_DL_DataModify(dataSource,
                               CSSM_DL_DB_RECORD_GENERIC,
                               uniqueRecordPtr,
                               &recordAttributeData,
                               0);

   if (result == CSSM_FAIL)
      status = CSSM_GetError()->error;

   delete [] distinguishedName;

   return status;
}


//**********************************************************************
//
// Directory Query APIs
//
//**********************************************************************


//------------------------------------------------------------
// function: JDL_QueryAttribute
//------------------------------------------------------------

uint32 
JDL_QueryAttribute(CSSM_DL_DB_HANDLE dataSource,
                   JDL_AttributeType attributeType,
                   asn_x500name& name, 
                   JDL_ATTRIBUTE_LIST_PTR& head)
{
   uint32 status = 0;

   //------------------------------------------------------------
   // Initialize return link list head pointer
   //------------------------------------------------------------

   head = 0;
   
   //------------------------------------------------------------
   // Convert ASN name to LDAP RFC1485 string
   //------------------------------------------------------------

   char* distinguishedName = 0;
   if ((status = convertNameToString(name, distinguishedName)) != 0)
      return status;

   //------------------------------------------------------------
   // populate CSSM_QUERY
   // NOTE: current LDAP DL retrieve's all attributes and values.
   //------------------------------------------------------------

   uint32 numOfPredicates = 2;
   CSSM_SELECTION_PREDICATE predicates[2];

   predicates[0].DbOperator = CSSM_DB_EQUAL;
   predicates[0].Attribute.Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
   predicates[0].Attribute.Info.AttributeName       = DL_SEARCH_SCOPE;
   predicates[0].Attribute.Value.Length             = strlen(DL_SCOPE_BASE) + 1;
   predicates[0].Attribute.Value.Data               = (unsigned char*)DL_SCOPE_BASE;

   predicates[1].DbOperator = CSSM_DB_EQUAL;
   predicates[1].Attribute.Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
   predicates[1].Attribute.Info.AttributeName       = DL_SEARCH_BASE;
   predicates[1].Attribute.Value.Length             = strlen(distinguishedName) + 1;
   predicates[1].Attribute.Value.Data               = (unsigned char*)distinguishedName;

   CSSM_QUERY query;
   switch (attributeType)
   {
   case JDL_ATTRIBUTE_CERT:
   case JDL_ATTRIBUTE_CA_CERT:
   case JDL_ATTRIBUTE_USER_CERT:
      query.RecordType = CSSM_DL_DB_RECORD_CERT;
      break;
   case JDL_ATTRIBUTE_CRL:
      query.RecordType = CSSM_DL_DB_RECORD_CRL;
      break;
   case JDL_ATTRIBUTE_CROSS_CERT_PAIR:
      query.RecordType = CSSM_DL_DB_X_CERT_PAIR;
      break;
   case JDL_ATTRIBUTE_CRL_DISTRIBUTION_POINT:
      query.RecordType = CSSM_DL_DB_CRL_DISTRIBUTION_POINT;
      break;
   case JDL_ATTRIBUTE_AUTHORITY_REVOCATION_LIST:
      query.RecordType = CSSM_DL_DB_AUTHORITY_REVOCATION_LIST;
      break;
   case JDL_ATTRIBUTE_DELTA_REVOCATION_LIST:
      query.RecordType = CSSM_DL_DB_DELTA_REVOCATION_LIST;
      break;
   default:
      return -1; // XXX
      break;
   }
   
   query.Conjunctive            = CSSM_DB_NONE;
   query.NumSelectionPredicates = numOfPredicates;
   query.SelectionPredicate     = predicates;
   query.QueryLimits.TimeLimit  = 0;
   query.QueryLimits.SizeLimit  = 0;
   query.QueryFlags             = 0;

   //------------------------------------------------------------
   // retrieve all attributes of selected type from given directory entry
   //------------------------------------------------------------

   CSSM_DB_UNIQUE_RECORD_PTR      uniqueRecordPtr = 0;
   CSSM_BOOL                      endOfDataStore  = CSSM_FALSE;
   CSSM_HANDLE                    resultHandle;
   CSSM_DB_RECORD_ATTRIBUTE_DATA  recAttributeData;
   CSSM_DATA                      recData;

   uniqueRecordPtr = CSSM_DL_DataGetFirst(dataSource,
                                          &query,
                                          &resultHandle,
                                          &endOfDataStore,
                                          &recAttributeData,
                                          &recData);

   if (!uniqueRecordPtr && endOfDataStore == CSSM_FALSE)
   {
      status = CSSM_GetError()->error;
   }
   else
   {
      for (uint32 j = 0; j < recAttributeData.NumberOfAttributes; j++)
      {
         if (CSSM_DB_ATTRIBUTE_NAME_AS_STRING == recAttributeData.AttributeData[j].Info.AttributeNameFormat)
         {
            if ( matchingAttributeName(attributeType, recAttributeData.AttributeData[j].Info.AttributeName) )
            {
               //------------------------------------------------------------
               // Explanation: we steal CSSM_DATA in AttributeData and 
               // give owership to linked list; caller must free data
               // use same CSSM memory functions
               //------------------------------------------------------------
               JDL_ATTRIBUTE_LIST_PTR node = (JDL_ATTRIBUTE_LIST_PTR)DefaultMalloc( sizeof(JDL_ATTRIBUTE_LIST) );
               node->next = 0;
               node->value = recAttributeData.AttributeData[j].Value;
               if (head) {
		            node->next = head;
		            head = node;
               } else {
		            head = node;
               }
               recAttributeData.AttributeData[j].Value.Data = 0;
               recAttributeData.AttributeData[j].Value.Length = 0;
            }
         }
      }
   }

   delete [] distinguishedName;

   return status;
}


//------------------------------------------------------------
// function: JDL_FreeAttributeList
//------------------------------------------------------------

void 
JDL_FreeAttributeList(JDL_ATTRIBUTE_LIST_PTR& head)
{
   JDL_ATTRIBUTE_LIST_PTR p;

   if (head)
   {
      while (head->next)
      {
         if ((p = head->next) != 0)
         {
            head->next = p->next;
            DefaultFree(p->value.Data);
            DefaultFree(p);
         }
      }
      DefaultFree(head->value.Data);
      DefaultFree(head); 
      head = 0;
   }
}


//------------------------------------------------------------
// function: JDL_QueryCACertificate
//------------------------------------------------------------

uint32 
JDL_QueryCACertificate(CSSM_DL_DB_HANDLE dataSource,
                       asn_x500name& issuer,
                       x509_certificate& cACertificate)
{
   uint32 status = 0;

   JDL_ATTRIBUTE_LIST_PTR head = 0;

   if ((status = JDL_QueryAttribute(dataSource,
                                    JDL_ATTRIBUTE_CERT,
                                    issuer, 
                                    head)) != 0)
      return status;

   // walk link link of returned CSSM_DATA structures

   JDL_ATTRIBUTE_LIST_PTR next = head;
   while (next)
   {
      r_buffer_t encoding;
      encoding.data = next->value.Data;
      encoding.data_len = next->value.Length;
      if ((status = cACertificate.read(encoding)) != 0)
         return status;
      next->value;
      next = next->next;
   }

   JDL_FreeAttributeList(head);

   return status;
}


//------------------------------------------------------------
// function: JDL_QueryUserCertificate
//------------------------------------------------------------

uint32
JDL_QueryUserCertificate(CSSM_DL_DB_HANDLE dataSource,
                         asn_x500name& subject, 
                         x509_certificate& userCertificate)
{
   uint32 status = 0;

   JDL_ATTRIBUTE_LIST_PTR head = 0;

   if ((status = JDL_QueryAttribute(dataSource,
                                    JDL_ATTRIBUTE_CERT,
                                    subject, 
                                    head)) != 0)
      return status;

   // walk link link of returned CSSM_DATA structures

   JDL_ATTRIBUTE_LIST_PTR next = head;
   while (next)
   {
      r_buffer_t encoding;
      encoding.data = next->value.Data;
      encoding.data_len = next->value.Length;
      if ((status = userCertificate.read(encoding)) != 0)
         return status;
      next = next->next;
   }

   JDL_FreeAttributeList(head);

   return status;
}


//------------------------------------------------------------
// function: JDL_QueryCRL
//------------------------------------------------------------

uint32
JDL_QueryCRL(CSSM_DL_DB_HANDLE dataSource,
             asn_x500name& issuer, 
             CertificateList& crl)
{
   uint32 status = 0;

   JDL_ATTRIBUTE_LIST_PTR head = 0;

   if ((status = JDL_QueryAttribute(dataSource,
                                    JDL_ATTRIBUTE_CRL,
                                    issuer, 
                                    head)) != 0)
      return status;

   // walk link link of returned CSSM_DATA structures

   JDL_ATTRIBUTE_LIST_PTR next = head;
   while (next)
   {
      r_buffer_t encoding;
      encoding.data = next->value.Data;
      encoding.data_len = next->value.Length;
      if ((status = crl.read(encoding)) != 0)
         return status;
      next = next->next;
   }

   JDL_FreeAttributeList(head);

   return status;
}


//**********************************************************************
//
// Directory Delete APIs
//
//**********************************************************************


uint32
JDL_DeleteDirectoryEntry(CSSM_DL_DB_HANDLE dataSource,
                         asn_x500name& directoryEntry)
{
   uint32 status = 0;

   CSSM_BOOL result;
   
   //------------------------------------------------------------
   // Convert ASN name to LDAP RFC1485 string
   //------------------------------------------------------------

   char* distinguishedName = 0;
   if ((status = convertNameToString(directoryEntry, distinguishedName)) != 0)
      return status;
      
   //------------------------------------------------------------
   // Create DL Unique Record
   //------------------------------------------------------------

   CSSM_DB_UNIQUE_RECORD_PTR uniqueRecordPtr = 0;
   CSSM_DB_UNIQUE_RECORD uniqueRecordID;

   uniqueRecordID.RecordIdentifier.Length = strlen(distinguishedName) + 1;
   uniqueRecordID.RecordIdentifier.Data = (unsigned char *) distinguishedName;
   uniqueRecordPtr = &uniqueRecordID;
   
   result = CSSM_DL_DataDelete(dataSource,
                               CSSM_DL_DB_RECORD_GENERIC,
                               uniqueRecordPtr);

   if (result == CSSM_FAIL)
      status = CSSM_GetError()->error;

   delete [] distinguishedName;

   return status;
}


//********************************************************************************
//
// CSSM memory management.
//
//********************************************************************************


//------------------------------------------------------------
// function: DefaultMalloc
//------------------------------------------------------------

void*
DefaultMalloc(uint32 size)
{
   return gMemoryFuncs.malloc_func(size, gMemoryFuncs.AllocRef);
}


//------------------------------------------------------------
// function: DefaultFree
//------------------------------------------------------------

void
DefaultFree(void* memPtr)
{
   gMemoryFuncs.free_func(memPtr, gMemoryFuncs.AllocRef);
}


//------------------------------------------------------------
// function: DefaultRealloc
//------------------------------------------------------------

void*
DefaultRealloc(void* memPtr,
               uint32 size)
{
   return gMemoryFuncs.realloc_func(memPtr, size, gMemoryFuncs.AllocRef);
}


//------------------------------------------------------------
// function: DefaultCalloc
//------------------------------------------------------------

void*
DefaultCalloc(uint32 num,
              uint32 size)
{
   return gMemoryFuncs.calloc_func(num, size, gMemoryFuncs.AllocRef);
}


//********************************************************************************
//
// Utility methods
//
//********************************************************************************


//------------------------------------------------------------
// function: convertNameToString
//------------------------------------------------------------

uint32
convertNameToString(asn_x500name& name, 
                    char*& nameString)
{
   uint32 status = 0;

   buffer_t utf8Buffer;

   if ((status = name.set_leading_rdn_separator(false)) != 0)
      return status;
   if ((status = name.set_rdn_separator(',')) != 0)
      return status;
   if ((status = name.set_ava_separator('+')) != 0)
      return status;
   if ((status = name.set_rdn_bigendian(false)) != 0)
      return status;
   if ((status = name.get_value_UTF8(utf8Buffer)) != 0)
      return status;

   // convert to null terminated string

   utf8Buffer.data;

   nameString = new char[utf8Buffer.data_len+1];
   memcpy(nameString, utf8Buffer.data, utf8Buffer.data_len);
   nameString[utf8Buffer.data_len] = '\0';

   return status;
}


//------------------------------------------------------------
// function: lookupAttributeName
//------------------------------------------------------------

const char*
lookupAttributeName(JDL_AttributeType attributeType)
{
   switch (attributeType)
   {
   case JDL_ATTRIBUTE_CA_CERT:
      return "cacertificate";
      break;
   case JDL_ATTRIBUTE_USER_CERT:
      return "usercertificate";
      break;
   case JDL_ATTRIBUTE_CRL:
      return "certificaterevocationlist";
      break;
   case JDL_ATTRIBUTE_CROSS_CERT_PAIR:
      return "crosscertificatepair";
      break;
   case JDL_ATTRIBUTE_CRL_DISTRIBUTION_POINT:
      return "crldistributionpoint";
      break;
   case JDL_ATTRIBUTE_AUTHORITY_REVOCATION_LIST:
      return "authorityrevocationlist";
      break;
   case JDL_ATTRIBUTE_DELTA_REVOCATION_LIST:
      return "deltarevocationlist";
      break;
   default:
      break;
   }
   return 0;
}


//------------------------------------------------------------
// function: matchingAttributeName
//------------------------------------------------------------

bool
matchingAttributeName(JDL_AttributeType attributeType, 
                      const char* attributeName)
{
   bool match = false;

   switch (attributeType)
   {
   case JDL_ATTRIBUTE_CERT:
      if ((strcmp(attributeName, "cacertificate") == 0) ||
          (strcmp(attributeName, "usercertificate") == 0))
      {
         match = true;
      }
      break;
   case JDL_ATTRIBUTE_CA_CERT:
      if (strcmp(attributeName, "cacertificate") == 0)
      {
         match = true;
      }
      break;
   case JDL_ATTRIBUTE_USER_CERT:
      if (strcmp(attributeName, "usercertificate") == 0)
      {
         match = true;
      }
      break;
   case JDL_ATTRIBUTE_CRL:
      if (strcmp(attributeName, "certificaterevocationlist") == 0)
      {
         match = true;
      }
      break;
   case JDL_ATTRIBUTE_CROSS_CERT_PAIR:
      if (strcmp(attributeName, "crosscertificatepair") == 0)
      {
         match = true;
      }
      break;
   case JDL_ATTRIBUTE_CRL_DISTRIBUTION_POINT:
      if (strcmp(attributeName, "crldistributionpoint") == 0)
      {
         match = true;
      }
      break;
   case JDL_ATTRIBUTE_AUTHORITY_REVOCATION_LIST:
      if (strcmp(attributeName, "authorityrevocationlist") == 0)
      {
         match = true;
      }
      break;
   case JDL_ATTRIBUTE_DELTA_REVOCATION_LIST:
      if (strcmp(attributeName, "deltarevocationlist") == 0)
      {
         match = true;
      }
      break;
   default:
      break;
   }

   return match;
}
