RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

attrib.c

Uses the procedures described in samples/common/include/attributil.h to parse and create attributes objects

/* $Id: attrib.c,v 1.4 2004/03/02 05:18:32 gsingh Exp $ */
/* attrib.c
** Copyright (c) 1999-2002, 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 uses the procedures described in
** samples/common/include/attributil.h to parse and create attributes
** objects.
**
** When compiling, define the macro RSA_REQUIRE_FILE_LOG (-D compile
** option, or equivelent) to force the program to return an error code
** if file logging cannot be initialized.  For example, if the file
** containing the log message format strings cannot be located (certc.msg
** or equivalent).
*/

#include "certc.h"
#include "filelog.h"
#include "demoutil.h"
#include "attributil.h"
#include "extnutil.h"

/*  DisplyAttributesObj obtains the BER encoding of an attributes 
 *  object from a file and then prints out the attributes in that
 *  attribute object.  An attributes object should already have
 *  been created and saved in a file.
 */
static int DisplayAttributesObj (void);

/*  GenerateAttributesObj creates an attribute object and then obtains
 *  user input to create attributes to put in the attributes object.
 *  It then stores the DER encoding of the attributes object in a file.
 */
static int GenerateAttributesObj (void);

/*  AddExtensionsToAttributesObj obtains the BER encoding of a 
 *  pregenerated extenstions object and sets this into an attributes
 *  object.  The user has the option of specifying a pregenerated
 *  attributes object that is stored in BER format.  If not attributes
 *  object is specified then a new one will be created. 
 *  C_GetAttributeInExtensionsObj is then called to create an 
 *  attribute field of type AT_X509_V3_EXTENSIONS and set this 
 *  attribute with the extensions object.  The attributes object 
 *  with the extensions object is then saved in binary DER format
 *  to a file.
 */
static int AddExtensionsToAttributesObj (CERTC_CTX ctx);

/*  AddExtenToAttribObjAlt performs the same functionality as
 *  AddExtensionsToAttributesObj except that the attribute is 
 *  added using C_AddAttributeValueBER.  In this case the attribute
 *  type of the extensions object is explicitly stated to be
 *  AT_X509_V3_EXTENSIONS.
 */
static int AddExtenToAttribObjAlt (CERTC_CTX ctx);

int main (int argc, char *argv[])
{
  int status = 0;
  char command[RSA_DEMO_MAX_LINE_LEN];

  CERTC_CTX ctx = NULL;

  FILE_LOG_PARAMS logParams = {NULL, NULL};
  SERVICE_HANDLER logHandler = {
    SPT_LOG, "Default File Log", S_InitializeFileLog
  };

  status = RSA_SetOptions (&logParams, argc, argv);
  if (status != 0)
    goto CLEANUP;

  status = C_InitializeCertC (NULL, NULL, 0, &ctx);
  if (status != 0)
    goto CLEANUP;

  /* Attempt to initialize file logging, but unless RSA_REQUIRE_FILE_LOG is
   * defined, treat it as a non-fatal condition.
   */
  status = C_RegisterService (ctx, &logHandler, (POINTER)&logParams,
                              SERVICE_ORDER_FIRST);
#ifdef RSA_REQUIRE_FILE_LOG
  if (status != 0)
    goto CLEANUP;
#endif

  RSA_PrintMessage ("Attributes Object Demonstration\n");
  RSA_PrintMessage ("===============================\n");

  for (;;) {
    RSA_PrintMessage ("\nAttributes Object Operations\n");
    RSA_PrintMessage ("  A - Display attributes object from a file\n");
    RSA_PrintMessage ("  B - Generate attributes object\n");
    RSA_PrintMessage ("  C - Add extensions object to attributes object\n");
    RSA_PrintMessage ("      using C_GetExtensionsInAttributesObj\n");
    RSA_PrintMessage ("  D - (alternate method)  Add extensions object to\n");
    RSA_PrintMessage ("      attributes object\n");
    status = RSA_GetCommand (command, sizeof (command),
                             "Enter choice (blank to quit)");
    if (status != 0)
      goto CLEANUP;

    switch (command[0]) {
      case 'a':
      case 'A':
        status = DisplayAttributesObj ();
        break;
      case 'b':
      case 'B':
        status = GenerateAttributesObj ();
        break;
      case 'c':
      case 'C':
        status = AddExtensionsToAttributesObj (ctx);
        break;
      case 'd':
      case 'D':
        status = AddExtenToAttribObjAlt (ctx);
        break;
      case '\0':
      case 'q':
      case 'Q':
        goto CLEANUP;
      default:
        RSA_PrintMessage ("Unrecognized Option: %c\n", command[0]);
        status = RSA_DEMO_E_INVALID_PARAMETER;
    }

    if (status != 0)
      RSA_PrintMessage ("Operation not completed.\n");
    else
      RSA_PrintMessage ("Operation successful!\n");
  }
    
CLEANUP:
  if (status != 0)
    RSA_PrintError ("attrib.c", status);

  C_FinalizeCertC (&ctx);

  return status;
}  /* end main */

/* See function declaration at the top for a description */
static int DisplayAttributesObj ()
{
  int status = 0;
  
  unsigned char *attribBer = NULL_PTR;
  unsigned int attribBerLen = 0;
  
  ATTRIBUTES_OBJ attribObj = (ATTRIBUTES_OBJ)NULL_PTR;

  status = RSA_GetFileToAllocBuffer (&attribBer, &attribBerLen,
                                     "Enter name of attributes object binary");
  if (status != 0)
    goto CLEANUP;

  status = C_CreateAttributesObject (&attribObj);
  if (status != 0)
    goto CLEANUP;

  status = C_SetAttributesBER (attribObj, attribBer, attribBerLen);
  if (status != 0)
    goto CLEANUP;

  /* RSA_PrintAttributesObject is defined in attributil.c */
  status = RSA_PrintAttributesObject ("\nAttributes Object Contents",
                                      attribObj);

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

  C_DestroyAttributesObject (&attribObj);
  T_free (attribBer);

  return status;
}  /* end DisplayAttributesObj */

/* See function declaration at the top for a description */
static int GenerateAttributesObj ()
{
  int status = 0;

  ATTRIBUTES_OBJ attribObj = (ATTRIBUTES_OBJ)NULL_PTR;

  unsigned char *attribBer = NULL_PTR;
  unsigned int attribBerLen = 0;

  status = C_CreateAttributesObject (&attribObj);
  if (status != 0)
    goto CLEANUP;

  /* RSA_GetInputToAttributesObject is defined in attributil.c. 
   * This function obtains user input to create attributes and
   * sets them into the attribObj.
   */
  status = RSA_GetInputToAttributesObject (attribObj);
  if (status != 0)
    goto CLEANUP;

  status = C_GetAttributesDER (attribObj, &attribBer, &attribBerLen);
  if (status != 0)
    goto CLEANUP;

  status = RSA_WriteDataToFile
           (attribBer, attribBerLen,
            "Enter file name to store attributes object binary");
  
CLEANUP:
  if (status != 0)
    RSA_PrintError ("GenerateAttributesObj", status);

  C_DestroyAttributesObject (&attribObj);
  
  return status;
}  /* end GenerateAttributesObj */

/* See function declaration at the top for a description */
static int AddExtensionsToAttributesObj (CERTC_CTX ctx)
{
  int status = 0, extenIndex = 0;
  unsigned char *extenBer = NULL, *attribBer = NULL;
  unsigned int extenBerLen = 0, attribBerLen = 0;

  EXTENSIONS_OBJ extenObjs[3] = {NULL, NULL, NULL};
  ATTRIBUTES_OBJ attribObj = NULL;

  unsigned char *newAttrib = NULL;
  unsigned int newAttribLen = 0;

  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;

  RSA_PrintMessage ("Enter name of file containing attributes object ");
  RSA_PrintMessage ("(blank to create a new object):\n");
  status = RSA_GetFileToAllocBuffer (&attribBer, &attribBerLen, NULL);
  if (status == RSA_DEMO_E_CANCEL)  /* blank is okay */
    status = 0;
  else if (status != 0)
    goto CLEANUP;

  /* Since we don't know ahead of time what kind of extensions we're dealing
   * with, create one of each type and try setting each one with the given
   * binary data.
   */
  status = C_CreateExtensionsObject (&extenObjs[0], CERT_EXTENSIONS_OBJ, ctx);
  if (status != 0)
    goto CLEANUP;
  status = C_CreateExtensionsObject (&extenObjs[1], CRL_EXTENSIONS_OBJ, ctx);
  if (status != 0)
    goto CLEANUP;
  status = C_CreateExtensionsObject (&extenObjs[2], CRL_ENTRY_EXTENSIONS_OBJ,
                                     ctx);
  if (status != 0)
    goto CLEANUP;

  for (extenIndex = 0; extenIndex < sizeof (extenObjs)/sizeof (extenObjs[0]);
       extenIndex++) {
    status = C_SetExtensionsObjectBER (extenObjs[extenIndex], extenBer,
                                       extenBerLen);
    if (status == 0)
      break;
  }
  if (status != 0)
    goto CLEANUP;  /* if none of the extenObjs could be used */

  status = C_CreateAttributesObject (&attribObj);
  if (status != 0)
    goto CLEANUP;

  if (attribBerLen != 0) {
    status = C_SetAttributesBER (attribObj, attribBer, attribBerLen);
    if (status != 0)
      goto CLEANUP;
  }

  status = C_GetAttributeInExtensionsObj (extenObjs[extenIndex], attribObj);
  if (status != 0)
    goto CLEANUP;

  status = C_GetAttributesDER (attribObj, &newAttrib, &newAttribLen);
  if (status != 0)
    goto CLEANUP;

  status = RSA_WriteDataToFile (newAttrib, newAttribLen,
           "Enter name of file to store new attributes object");

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

  for (extenIndex = 0; extenIndex < sizeof (extenObjs)/sizeof (extenObjs[0]);
       extenIndex++)
    C_DestroyExtensionsObject (&extenObjs[extenIndex]);
  T_free (extenBer);
  T_free (attribBer);
  
  return status;
}  /* end AddExtensionsToAttributesObj */

/* See function declaration at the top for a description */
static int AddExtenToAttribObjAlt (CERTC_CTX ctx)
{
  int status = 0, extenIndex = 0;
  unsigned char *extenBer = NULL, *attribBer = NULL;
  unsigned int extenBerLen = 0, attribBerLen = 0;

  EXTENSIONS_OBJ extenObjs[3] = {NULL, NULL, NULL};
  ATTRIBUTES_OBJ attribObj = NULL;

  unsigned char *newAttrib = NULL;
  unsigned int newAttribLen = 0;

  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;

  RSA_PrintMessage ("Enter name of file containing attributes object ");
  RSA_PrintMessage ("(blank to create a new object):\n");
  status = RSA_GetFileToAllocBuffer (&attribBer, &attribBerLen, NULL);
  if (status == RSA_DEMO_E_CANCEL)  /* blank is okay */
    status = 0;
  else if (status != 0)
    goto CLEANUP;

  /* Since we don't know ahead of time what kind of extensions we're dealing
   * with, create one of each type and try setting each one with the given
   * binary data.
   */
  status = C_CreateExtensionsObject (&extenObjs[0], CERT_EXTENSIONS_OBJ, ctx);
  if (status != 0)
    goto CLEANUP;
  status = C_CreateExtensionsObject (&extenObjs[1], CRL_EXTENSIONS_OBJ, ctx);
  if (status != 0)
    goto CLEANUP;
  status = C_CreateExtensionsObject (&extenObjs[2], CRL_ENTRY_EXTENSIONS_OBJ,
                                     ctx);
  if (status != 0)
    goto CLEANUP;

  /* We go through the trouble of setting an extensions object to verify that
   * what the user provided is actually a valid encoding of an extensions
   * object.
   */
  for (extenIndex = 0; extenIndex < sizeof (extenObjs)/sizeof (extenObjs[0]);
       extenIndex++) {
    status = C_SetExtensionsObjectBER (extenObjs[extenIndex], extenBer,
                                       extenBerLen);
    if (status == 0)
      break;
  }
  if (status != 0)
    goto CLEANUP;  /* if none of the extenObjs could be used */

  status = C_CreateAttributesObject (&attribObj);
  if (status != 0)
    goto CLEANUP;

  if (attribBerLen != 0) {
    status = C_SetAttributesBER (attribObj, attribBer, attribBerLen);
    if (status != 0)
      goto CLEANUP;
  }

  status = C_AddAttributeValueBER (attribObj, AT_X509_V3_EXTENSIONS,
                                   AT_X509_V3_EXTENSIONS_LEN, extenBer,
                                   extenBerLen);
  if (status != 0)
    goto CLEANUP;

  status = C_GetAttributesDER (attribObj, &newAttrib, &newAttribLen);
  if (status != 0)
    goto CLEANUP;

  status = RSA_WriteDataToFile (newAttrib, newAttribLen,
           "Enter name of file to store new attributes object");
  if (status != 0)
    goto CLEANUP;

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

  for (extenIndex = 0; extenIndex < sizeof (extenObjs)/sizeof (extenObjs[0]);
       extenIndex++)
    C_DestroyExtensionsObject (&extenObjs[extenIndex]);
  T_free (extenBer);
  T_free (attribBer);
  
  return status;
}  /* end AddExtenToAttribObjAlt */

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