RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

extnutil.c

Prints information contained in an Extensions object. Gathers user input to place into an extensions object.

/* $Id: extnutil.c,v 1.7 2004/03/02 05:18:37 gsingh Exp $ */
/* extnutil.c
** Copyright (c) 1999-2003, RSA Security Inc.
**
** This file is used to demonstrate how to interface to an RSA Security
** licensed development product.  You have a royalty-free right to use,
** modify, reproduce and distribute this demonstration file (including
** any modified version), provided that you agree that RSA Security has
** no warranty, implied or otherwise, or liability for this demonstration
** file or any modified version.
**
** This file contains routines that are used to print the information
** contained in an extensions object in a readable manner, as well as
** routines used to gather user input to place into an extensions object.
*/

#include "extnutil.h"

#ifdef _MSC_VER
# pragma warning (disable: 171) /* invalid type conversion (often of very similar ptrs) */
#endif

static RSA_DEMO_TABLE_ENTRY RSA_DEMO_CERT_ET_TABLE[RSA_DEMO_CERT_ET_COUNT];
static RSA_DEMO_TABLE_ENTRY RSA_DEMO_CRL_ET_TABLE[RSA_DEMO_CRL_ET_COUNT];
static RSA_DEMO_TABLE_ENTRY RSA_DEMO_CRL_ENTRY_ET_TABLE[RSA_DEMO_CRL_ENTRY_ET_COUNT];

static void InitCertEtTable () {
  static int flag = 0;

  if (flag)
    return;
  flag = 1;

  T_memset ((POINTER)&RSA_DEMO_CERT_ET_TABLE, 0,
            sizeof (RSA_DEMO_CERT_ET_TABLE));

  RSA_DEMO_CERT_ET_TABLE[0].description = "Basic Constraints";
  RSA_DEMO_CERT_ET_TABLE[0].val.etEntry.et.data = ET_BASIC_CONSTRAINTS;
  RSA_DEMO_CERT_ET_TABLE[0].val.etEntry.et.len = ET_BASIC_CONSTRAINTS_LEN;
  RSA_DEMO_CERT_ET_TABLE[0].val.etEntry.print = PrintBasicConstraintsInfo;
  RSA_DEMO_CERT_ET_TABLE[0].val.etEntry.prompt = BasicConstraintsInfoPrompt;
  RSA_DEMO_CERT_ET_TABLE[0].val.etEntry.infoSize = sizeof (BASIC_CONSTRAINTS);
  RSA_DEMO_CERT_ET_TABLE[1].description = "Key Usage";
  RSA_DEMO_CERT_ET_TABLE[1].val.etEntry.et.data = ET_KEY_USAGE;
  RSA_DEMO_CERT_ET_TABLE[1].val.etEntry.et.len = ET_KEY_USAGE_LEN;
  RSA_DEMO_CERT_ET_TABLE[1].val.etEntry.print = PrintKeyUsageValue;
  RSA_DEMO_CERT_ET_TABLE[1].val.etEntry.prompt = KeyUsageValuePrompt;
  RSA_DEMO_CERT_ET_TABLE[1].val.etEntry.infoSize = sizeof (UINT4);
  RSA_DEMO_CERT_ET_TABLE[2].description = "Extended Key Usage";
  RSA_DEMO_CERT_ET_TABLE[2].val.etEntry.et.data = ET_EXTENDED_KEY_USAGE;
  RSA_DEMO_CERT_ET_TABLE[2].val.etEntry.et.len = ET_EXTENDED_KEY_USAGE_LEN;
  RSA_DEMO_CERT_ET_TABLE[2].val.etEntry.print = PrintExtendedKeyUsageValue;
  RSA_DEMO_CERT_ET_TABLE[2].val.etEntry.prompt = ExtendedKeyUsageValuePrompt;
  RSA_DEMO_CERT_ET_TABLE[2].val.etEntry.infoSize = sizeof (EXTENDED_KEY_USAGE);
  RSA_DEMO_CERT_ET_TABLE[3].description = "Certificate Policies";
  RSA_DEMO_CERT_ET_TABLE[3].val.etEntry.et.data = ET_CERT_POLICIES;
  RSA_DEMO_CERT_ET_TABLE[3].val.etEntry.et.len = ET_CERT_POLICIES_LEN;
  RSA_DEMO_CERT_ET_TABLE[3].val.etEntry.print = PrintCertPolicyValue;
  RSA_DEMO_CERT_ET_TABLE[3].val.etEntry.prompt = CertPolicyValuePrompt;
  RSA_DEMO_CERT_ET_TABLE[3].val.etEntry.destroyInternals =
    DestroyPolicyValueInternals;
  RSA_DEMO_CERT_ET_TABLE[3].val.etEntry.infoSize = sizeof (POLICY_INFO);
  RSA_DEMO_CERT_ET_TABLE[4].description = "Private Key Usage Period";
  RSA_DEMO_CERT_ET_TABLE[4].val.etEntry.et.data = ET_PRIVATE_KEY_USAGE_PERIOD;
  RSA_DEMO_CERT_ET_TABLE[4].val.etEntry.et.len =
    ET_PRIVATE_KEY_USAGE_PERIOD_LEN;
  RSA_DEMO_CERT_ET_TABLE[4].val.etEntry.print =
    PrintPrivateKeyUsagePeriodValue;
  RSA_DEMO_CERT_ET_TABLE[4].val.etEntry.prompt =
    PrivateKeyUsagePeriodValuePrompt;
  RSA_DEMO_CERT_ET_TABLE[4].val.etEntry.infoSize =
    sizeof (PRIVATE_KEY_USAGE_PERIOD);
  RSA_DEMO_CERT_ET_TABLE[5].description = "CRL Distribution Points";
  RSA_DEMO_CERT_ET_TABLE[5].val.etEntry.et.data = ET_CRL_DISTRIBUTION_POINTS;
  RSA_DEMO_CERT_ET_TABLE[5].val.etEntry.et.len =
    ET_CRL_DISTRIBUTION_POINTS_LEN;
  RSA_DEMO_CERT_ET_TABLE[5].val.etEntry.print =
    PrintCrlDistributionPointsValue;
  RSA_DEMO_CERT_ET_TABLE[5].val.etEntry.prompt =
    CrlDistributionPointsValuePrompt;
  RSA_DEMO_CERT_ET_TABLE[5].val.etEntry.destroyInternals = 
    DestroyCrlDistributionPointInternals;
  RSA_DEMO_CERT_ET_TABLE[5].val.etEntry.infoSize = sizeof (DISTRIBUTION_POINT);
  /*  If you want to add more entries here, be sure to update the definition of
   *  RSA_DEMO_ET_COUNT in extnutil.h!
   */
}  /* end InitCertEtTable */

static void InitCrlEtTable () {
  static int flag = 0;

  if (flag)
    return;
  flag = 1;

  T_memset ((POINTER)&RSA_DEMO_CRL_ET_TABLE, 0,
            sizeof (RSA_DEMO_CRL_ET_TABLE));

  RSA_DEMO_CRL_ET_TABLE[0].description = "CRL Number";
  RSA_DEMO_CRL_ET_TABLE[0].val.etEntry.et.data = ET_CRL_NUMBER;
  RSA_DEMO_CRL_ET_TABLE[0].val.etEntry.et.len = ET_CRL_NUMBER_LEN;
  RSA_DEMO_CRL_ET_TABLE[0].val.etEntry.print = PrintCrlNumberValue;
  RSA_DEMO_CRL_ET_TABLE[0].val.etEntry.prompt = CrlNumberValuePrompt;
  RSA_DEMO_CRL_ET_TABLE[0].val.etEntry.infoSize = sizeof (ITEM);
  RSA_DEMO_CRL_ET_TABLE[1].description = "Delta CRL Indicator";
  RSA_DEMO_CRL_ET_TABLE[1].val.etEntry.et.data = ET_DELTA_CRL_INDICATOR;
  RSA_DEMO_CRL_ET_TABLE[1].val.etEntry.et.len = ET_DELTA_CRL_INDICATOR_LEN;
  RSA_DEMO_CRL_ET_TABLE[1].val.etEntry.print = PrintDeltaCrlValue;
  RSA_DEMO_CRL_ET_TABLE[1].val.etEntry.prompt = DeltaCrlValuePrompt;
  RSA_DEMO_CRL_ET_TABLE[1].val.etEntry.infoSize = sizeof (ITEM);
}  /* end InitCrlEtTable */

static void InitCrlEntryEtTable () {
  static int flag = 0;

  if (flag)
    return;
  flag = 1;

  T_memset ((POINTER)&RSA_DEMO_CRL_ENTRY_ET_TABLE, 0,
            sizeof (RSA_DEMO_CRL_ENTRY_ET_TABLE));

  RSA_DEMO_CRL_ENTRY_ET_TABLE[0].description = "Reason Code";
  RSA_DEMO_CRL_ENTRY_ET_TABLE[0].val.etEntry.et.data = ET_REASON_CODE;
  RSA_DEMO_CRL_ENTRY_ET_TABLE[0].val.etEntry.et.len = ET_REASON_CODE_LEN;
  RSA_DEMO_CRL_ENTRY_ET_TABLE[0].val.etEntry.print = PrintReasonCodeValue;
  RSA_DEMO_CRL_ENTRY_ET_TABLE[0].val.etEntry.prompt = ReasonCodeValuePrompt;
  RSA_DEMO_CRL_ENTRY_ET_TABLE[0].val.etEntry.infoSize = sizeof (unsigned int);
}  /* end InitCrlEntryEtTable */

int RSA_ExtenTypePromptAlloc (unsigned int type, unsigned char **extenType,
                              unsigned int *extenTypeLen, int *criticality,
                              POINTER *extenTypeInfo)
{
  int status = 0, choice = 0;
  RSA_DEMO_TABLE_ENTRY *tableEntry = (RSA_DEMO_TABLE_ENTRY *)NULL_PTR;

  *extenTypeInfo = NULL_PTR;

  switch (type) {
    case CERT_EXTENSIONS_OBJ:
      InitCertEtTable ();      
      RSA_PrintMessage ("Certificate Extension Type Choices\n");
      status = ChooseTableEntryPrompt (RSA_DEMO_CERT_ET_TABLE,
                                       RSA_DEMO_CERT_ET_COUNT, &tableEntry);
      break;
    case CRL_EXTENSIONS_OBJ:
      InitCrlEtTable ();
      RSA_PrintMessage ("CRL Extension Type Choices\n");
      status = ChooseTableEntryPrompt (RSA_DEMO_CRL_ET_TABLE,
                                       RSA_DEMO_CRL_ET_COUNT, &tableEntry);
      break;
    case CRL_ENTRY_EXTENSIONS_OBJ:
      InitCrlEntryEtTable ();
      RSA_PrintMessage ("CRL Entry Extension Type Choices\n");
      status = ChooseTableEntryPrompt (RSA_DEMO_CRL_ENTRY_ET_TABLE,
                                       RSA_DEMO_CRL_ENTRY_ET_COUNT,
                                       &tableEntry);
      break;
    default:
      status = RSA_DEMO_E_INVALID_PARAMETER;
  }
  if (status != 0)
    goto CLEANUP;

  *extenType = tableEntry->val.etEntry.et.data;
  *extenTypeLen = tableEntry->val.etEntry.et.len;

  RSA_PrintMessage ("Criticality\n");
  RSA_PrintMessage ("  1 - Critical\n");
  RSA_PrintMessage ("  2 - Non-critical\n");
  status = RSA_GetInteger (&choice, "Enter an integer (blank for default)");
  if (status == RSA_DEMO_E_CANCEL) {
    status = 0;
    *criticality = NOT_IN_USE;
  }
  else if (status == 0)
    switch (choice) {
      case 1:
        *criticality = CRITICAL;
        break;
      case 2:
        *criticality = NON_CRITICAL;
        break;
      default:
        RSA_PrintMessage ("Invalid integer.  Defaulting to NOT_IN_USE.\n");
        *criticality = NOT_IN_USE;
    }
  else
    goto CLEANUP;

  *extenTypeInfo = T_malloc (tableEntry->val.etEntry.infoSize);
  status = tableEntry->val.etEntry.prompt (*extenTypeInfo);
  if (status != 0)
    goto CLEANUP;

CLEANUP:
  if (status != 0) {
    *extenType = NULL_PTR;
    *extenTypeLen = 0;
    T_free (*extenTypeInfo);
    *extenTypeInfo = NULL_PTR;
  }

  if (status != 0)
    RSA_PrintError ("RSA_ExtenTypePromptAlloc", status);

  return status;
}  /* end RSA_ExtenTypePromptAlloc */

int RSA_DestroyExtenTypeInfo (unsigned char *extenType,
                              unsigned int extenTypeLen,
                              POINTER *extenTypeInfo)
{
  int status = 0;

  int (*destroyInternals) (POINTER info) = NULL;

  status = RSA_GetExtnDestroyInternalsFn (extenType, extenTypeLen,
                                          &destroyInternals);
  if (status != 0)
    goto CLEANUP;

  if (destroyInternals != NULL)
    status = (*destroyInternals) (*extenTypeInfo);

CLEANUP:
  T_free (*extenTypeInfo);
  *extenTypeInfo = NULL_PTR;

  if (status != 0)
    RSA_PrintError ("RSA_DestroyExtenTypeInfo", status);

  return status;
}  /* end RSA_DestroyExtenTypeInfo */

int RSA_GetExtenTypeDesc (unsigned char *extenType, unsigned int extenTypeLen,
                          char **desc)
{
  int status = 0, i = 0;

  InitCertEtTable ();
  InitCrlEtTable ();
  InitCrlEntryEtTable ();
  *desc = (char *)NULL_PTR;

  /*  check if it's a cert extension...  */
  for (i = 0; i < RSA_DEMO_CERT_ET_COUNT; i++)
    if (extenTypeLen == RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.et.len &&
        T_memcmp (extenType, RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.et.data,
                  RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.et.len) == 0) {
      *desc = RSA_DEMO_CERT_ET_TABLE[i].description;
      break;
    }

  if (*desc != (char *)NULL_PTR)
    goto CLEANUP;

  /*  check if it's a CRL extension...  */
  for (i = 0; i < RSA_DEMO_CRL_ET_COUNT; i++)
    if (extenTypeLen == RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.et.len &&
        T_memcmp (extenType, RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.et.data,
                  RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.et.len) == 0) {
      *desc = RSA_DEMO_CRL_ET_TABLE[i].description;
      break;
    }

  if (*desc != (char *)NULL_PTR)
    goto CLEANUP;
  
  /*  check if it's a CRL entry extension... */
  for (i = 0; i < RSA_DEMO_CRL_ENTRY_ET_COUNT; i++)
    if (extenTypeLen == RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.et.len &&
        T_memcmp (extenType,
                  RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.et.data,
                  RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.et.len) == 0) {
      *desc = RSA_DEMO_CRL_ENTRY_ET_TABLE[i].description;
      break;
    }

  if (*desc == (char *)NULL_PTR)
    status = RSA_DEMO_E_NOT_FOUND;
  
CLEANUP:
  
  return status;
}  /* end RSA_GetExtenTypeDesc */

int RSA_GetExtnPrintFn (unsigned char *extenType, unsigned int extenTypeLen,
                        int (**printFn) (POINTER info))
{
  int status = 0, i = 0;

  InitCertEtTable ();
  InitCrlEtTable ();
  InitCrlEntryEtTable ();  
  *printFn = NULL;

  /*  check if it's a cert extension...  */
  for (i = 0; i < RSA_DEMO_CERT_ET_COUNT; i++)
    if (extenTypeLen == RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.et.len &&
        T_memcmp (extenType, RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.et.data,
                  RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.et.len) == 0) {
      *printFn = RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.print;
      break;
    }

  if (*printFn != NULL)
    goto CLEANUP;

  /*  check if it's a CRL extension...  */
  for (i = 0; i < RSA_DEMO_CRL_ET_COUNT; i++)
    if (extenTypeLen == RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.et.len &&
        T_memcmp (extenType, RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.et.data,
                  RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.et.len) == 0) {
      *printFn = RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.print;
      break;
    }

  if (*printFn != NULL)
    goto CLEANUP;

  /*  check if it's a CRL entry extension...  */
  for (i = 0; i < RSA_DEMO_CRL_ENTRY_ET_COUNT; i++)
    if (extenTypeLen == RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.et.len &&
        T_memcmp (extenType,
                  RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.et.data,
                  RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.et.len) == 0) {
      *printFn = RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.print;
      break;
    }
  
  if (*printFn == NULL)
    status = RSA_DEMO_E_NOT_FOUND;

CLEANUP:

  return status;
}  /* end RSA_GetExtnPrintFn */

int RSA_GetExtnDestroyInternalsFn (unsigned char *extenType,
                                   unsigned int extenTypeLen,
                                   int (**destroyInternalsFn) (POINTER info))
{
  int status = 0, i = 0;

  InitCertEtTable ();
  InitCrlEtTable ();
  InitCrlEntryEtTable ();  
  *destroyInternalsFn = NULL;

  /*  check if it's a cert extension...  */
  for (i = 0; i < RSA_DEMO_CERT_ET_COUNT; i++)
    if (extenTypeLen == RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.et.len &&
        T_memcmp (extenType, RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.et.data,
                  RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.et.len) == 0) {
      *destroyInternalsFn =
        RSA_DEMO_CERT_ET_TABLE[i].val.etEntry.destroyInternals;
      goto CLEANUP;  /* found entry, done */
    }

  /*  check if it's a CRL extension...  */
  for (i = 0; i < RSA_DEMO_CRL_ET_COUNT; i++)
    if (extenTypeLen == RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.et.len &&
        T_memcmp (extenType, RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.et.data,
                  RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.et.len) == 0) {
      *destroyInternalsFn =
        RSA_DEMO_CRL_ET_TABLE[i].val.etEntry.destroyInternals;
      goto CLEANUP;  /* found entry, done */
    }

  /*  check if it's a CRL entry extension...  */
  for (i = 0; i < RSA_DEMO_CRL_ENTRY_ET_COUNT; i++)
    if (extenTypeLen == RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.et.len &&
        T_memcmp (extenType,
                  RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.et.data,
                  RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.et.len) == 0) {
      *destroyInternalsFn =
        RSA_DEMO_CRL_ENTRY_ET_TABLE[i].val.etEntry.destroyInternals;
      goto CLEANUP;  /* found entry, done */
    }
  
  /* Note that *destroyInternalsFn can be NULL, but if that were true, we
     would have set *destroyInternalsFn to NULL and proceeded to the CLEANUP
     section in one of the loops above.  If we get here and
     *destroyInternalsFn is NULL, that means that we could not find an entry
     for the given extension type. */
  if (*destroyInternalsFn == NULL)
    status = RSA_DEMO_E_NOT_FOUND;

CLEANUP:

  return status;
}  /* end RSA_GetExtnPrintFn */

int RSA_PrintExtensionsObject (EXTENSIONS_OBJ extenObj)
{
  int status = 0;
  unsigned int extenCount = 0, i = 0, j = 0;

  unsigned char *extenBer = NULL;
  unsigned int extenBerLen = 0;

  EXTENSION_INFO extenInfo;
  char *extenString = NULL;
  int (*printExtenValue) (POINTER info) = NULL;
  POINTER extenValue = NULL_PTR;
  
  status = C_GetExtensionCount (extenObj, &extenCount);
  if (status != 0)
    goto CLEANUP;

  /*  Examine each extension in the extensions object  */
  for (i = 0; i < extenCount; i++) {
    RSA_PrintMessage ("*****\n");

    status = C_GetExtensionInfo (extenObj, i, &extenInfo);
    if (status != 0)
      goto CLEANUP;

    /*  Print extension value  */
    status = RSA_GetExtenTypeDesc (extenInfo.type, extenInfo.typeLen,
                                   &extenString);
    if (status == RSA_DEMO_E_NOT_FOUND) {
      RSA_PrintMessage ("Unrecognized Extension, ");
      status = 0;
    }
    else if (status != 0)
      goto CLEANUP;
    else
      RSA_PrintMessage ("%s, ", extenString);

    switch (extenInfo.criticalFlag) {
      case CRITICAL:
        RSA_PrintMessage ("Critical\n");
        break;
      case NON_CRITICAL:
        RSA_PrintMessage ("Non-critical\n");
        break;
      default:
        RSA_PrintMessage ("Unknown criticality\n");
    }

    status = RSA_GetExtnPrintFn (extenInfo.type, extenInfo.typeLen,
                                 &printExtenValue);
    if (status == RSA_DEMO_E_NOT_FOUND) {
      status = C_GetExtensionDER (extenObj, i, &extenBer, &extenBerLen);
      if (status != 0)
        goto CLEANUP;

      RSA_PrintBuf (" BER-encoded extension", extenBer, extenBerLen);
      continue;  /* we're done */
    }
    else if (status != 0)
      goto CLEANUP;

    /*  Examine each value for this particular extension  */
    for (j = 0; j < extenInfo.valueCount; j++) {
      if (extenInfo.valueCount > 1)
        RSA_PrintMessage ("  Value #%u:\n", j+1);

      status = C_GetExtensionValue (extenObj, i, j, &extenValue);
      if (status != 0)
        goto CLEANUP;
      
      status = (*printExtenValue) (extenValue);
      if (status != 0)
        goto CLEANUP;
    }
  }

CLEANUP:
  if (status != 0)
    RSA_PrintError ("RSA_PrintExtensionsObject", status);

  return status;
}  /* end RSA_PrintExtensionsObject */

int RSA_GetInputToExtensionsObject (EXTENSIONS_OBJ extenObj, unsigned int type)
{
  int status = 0;

  unsigned char *extenType = NULL;
  unsigned int extenTypeLen = 0, extenIndex = 0;
  int criticality = 0;
  POINTER extenValue = NULL_PTR;

  /*  Keep going until user enters a blank (just hits return in response to the
   *  prompt).
   */
  for (;;) {
    status = RSA_ExtenTypePromptAlloc (type, &extenType, &extenTypeLen,
                                       &criticality, &extenValue);
    if (status == RSA_DEMO_E_CANCEL) {
      status = 0;
      break;
    }
    else if (status != 0)
      goto CLEANUP;

    /*  Obtain an index to the extension in the extensions object by either
     *  creating a new extension or retrieving the index of the existing one.
     */
    status = C_CreateExtension (extenObj, extenType, extenTypeLen, &extenIndex,
                                criticality, (EXTENSION_HANDLER *)NULL_PTR);
    if (status == E_EXTENSION_ALREADY_EXISTS)
      status = C_FindExtensionByType (extenObj, extenType, extenTypeLen,
                                      &extenIndex);
    if (status != 0)
      goto CLEANUP;
    
    status = C_AddExtensionValue (extenObj, extenIndex, extenValue,
                                  (unsigned int *)NULL_PTR);
    if (status != 0) {
      RSA_PrintError ("adding extension value to extensions object", status);
      RSA_PrintMessage ("Try again.\n");
    }

    status = RSA_DestroyExtenTypeInfo (extenType, extenTypeLen, &extenValue);
    if (status != 0)
      goto CLEANUP;
  }
  
CLEANUP:
  if (status != 0)
    RSA_PrintError ("RSA_GetInputToExtensionsObject", status);

  T_free (extenValue);  
  
  return status;
}  /* end RSA_GetInputToExtensionsObject */

int RSA_GetExtensionsObject (EXTENSIONS_OBJ extensionsObj, unsigned int type)
{
  int status = 0;
  unsigned char *extenDer = NULL_PTR;
  unsigned int extenDerLen = 0;

  RSA_PrintMessage ("Enter name of file containing ");
  if (type == CERT_EXTENSIONS_OBJ)
    RSA_PrintMessage ("cert ");
  else if (type == CRL_EXTENSIONS_OBJ)
    RSA_PrintMessage ("CRL ");
  else if (type == CRL_ENTRY_EXTENSIONS_OBJ)
    RSA_PrintMessage ("CRL entries ");
  RSA_PrintMessage ("extensions object binary\n");

  status = RSA_GetFileToAllocBuffer
           (&extenDer, &extenDerLen,
            "(blank to create a new extensions object)");
  if (status == RSA_DEMO_E_CANCEL) {
    status = RSA_GetInputToExtensionsObject (extensionsObj, type);
    /* whatever happens, we're done here */
    goto CLEANUP;
  }
  if (status != 0)
    goto CLEANUP;

  status = C_SetExtensionsObjectBER (extensionsObj, extenDer, extenDerLen);
  if (status != 0)
    goto CLEANUP;

CLEANUP:
  if (status != 0)
    RSA_PrintError ("RSA_GetExtensionsObject", status);

  T_free (extenDer);

  return status;
}  /* end RSA_GetExtensionsObject */

int RSA_GetFileToExtensionsObject (CERTC_CTX ctx, EXTENSIONS_OBJ *extensionsObj)
{
  int status = 0, i = 0;
  unsigned char *extenBer = NULL;
  unsigned int extenBerLen = 0;

  unsigned int extenTypes[3] = {
    CERT_EXTENSIONS_OBJ, CRL_EXTENSIONS_OBJ, CRL_ENTRY_EXTENSIONS_OBJ
  };

  *extensionsObj = NULL;
  
  RSA_PrintMessage ("Enter name of file containing extensions object binary ");
  RSA_PrintMessage ("(blank to cancel):\n");
  status = RSA_GetFileToAllocBuffer (&extenBer, &extenBerLen, NULL);
  if (status != 0)
    goto CLEANUP;

  for (i = 0; i < sizeof (extenTypes)/sizeof (extenTypes[0]); i++) {
    status = C_CreateExtensionsObject (extensionsObj, extenTypes[i], ctx);
    if (status != 0)
      goto CLEANUP;

    status = C_SetExtensionsObjectBER (*extensionsObj, extenBer,
                                       extenBerLen);
    if (status == 0)
      break;

    C_DestroyExtensionsObject (extensionsObj);
  }
  if (status != 0)
    goto CLEANUP;  /* if none of the extenObjs could be used */

CLEANUP:
  if (status != 0) {
    RSA_PrintError ("RSA_GetFileToExtensionsObject", status);
    C_DestroyExtensionsObject (extensionsObj);
  }
  
  T_free (extenBer);

  return status;
}  /* end RSA_GetFileToExtensionsObject */

Copyright (c) 1999-2005 RSA Security Inc. All rights reserved. 067-001001-2720-001-000 - 2.7.2