RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

attributil.c

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

/* $Id: attributil.c,v 1.8 2004/03/02 05:18:37 gsingh Exp $ */
/* attributil.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 attributes object in a readable manner, as well as
** routines used to gather user input to place into an attributes object.
*/

#include "attributil.h"
#include "timeutil.h"
#include "extnutil.h"

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

unsigned char AT_SIGNING_TIME[AT_SIGNING_TIME_LEN] = {
  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05
};

unsigned char AT_CHALLENGE_PASSWORD[AT_CHALLENGE_PASSWORD_LEN] = {
  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x07
};

unsigned char AT_POSTAL_ADDRESS[AT_POSTAL_ADDRESS_LEN] = {
  0x55, 0x04, 0x10
};

static void InitAttrTable (void);

RSA_DEMO_TABLE_ENTRY RSA_DEMO_ATTR_TABLE[RSA_DEMO_ATTR_COUNT];

int RSA_AttrObjEntryTypePrompt (unsigned char **attribType,
                                unsigned int *attribTypeLen)
{
  int status = 0;
  RSA_DEMO_TABLE_ENTRY *tableEntry = (RSA_DEMO_TABLE_ENTRY *)NULL_PTR;

  InitAttrTable ();

  RSA_PrintMessage ("Attribute Type Choices\n");
  status = ChooseTableEntryPrompt (RSA_DEMO_ATTR_TABLE, RSA_DEMO_ATTR_COUNT,
                                   &tableEntry);
  if (status != 0) {
    *attribType = NULL_PTR;
    *attribTypeLen = 0;
    goto CLEANUP;
  }

  *attribType = tableEntry->val.atEntry.at.data;
  *attribTypeLen = tableEntry->val.atEntry.at.len;

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

  return status;
}  /* end RSA_AttrObjEntryTypePrompt */

int RSA_GetAttrObjEntryTypeDesc (unsigned char *attribType,
                                 unsigned int attribTypeLen, char **desc)
{
  int status = 0, i = 0;

  InitAttrTable ();
  *desc = (char *)NULL_PTR;

  for (i = 0; i < RSA_DEMO_ATTR_COUNT; i++)
    if (attribTypeLen == RSA_DEMO_ATTR_TABLE[i].val.at.len &&
        T_memcmp (attribType, RSA_DEMO_ATTR_TABLE[i].val.at.data,
                  RSA_DEMO_ATTR_TABLE[i].val.at.len) == 0) {
      *desc = RSA_DEMO_ATTR_TABLE[i].description;
      break;
    }

  if (*desc == (char *)NULL_PTR)
    status = RSA_DEMO_E_NOT_FOUND;

  return status;
}  /* end RSA_GetAttribTypeDesc */

int RSA_GetAttrObjEntryPrintFn
   (unsigned char *attribType, unsigned int attribTypeLen,
    int (**printFn) (ATTRIBUTES_OBJ, unsigned char *, unsigned int))
{
  int status = 0, i = 0;
  *printFn = NULL;

  InitAttrTable ();

  for (i = 0; i < RSA_DEMO_ATTR_COUNT; i++)
    if (attribTypeLen == RSA_DEMO_ATTR_TABLE[i].val.atEntry.at.len &&
        T_memcmp (attribType, RSA_DEMO_ATTR_TABLE[i].val.atEntry.at.data,
                  RSA_DEMO_ATTR_TABLE[i].val.atEntry.at.len) == 0) {
      *printFn = RSA_DEMO_ATTR_TABLE[i].val.atEntry.print;
      break;
    }

  if (*printFn == NULL)
    status = RSA_DEMO_E_NOT_FOUND;

  return status;
}  /* end RSA_GetAttrObjEntryPrintFn */

static int PrintUnrecognizedAttribute (ATTRIBUTES_OBJ attribObj,
                                       unsigned char *type,
                                       unsigned int typeLen)
{
  int status = 0;
  unsigned int i = 0, valueCount = 0;

  unsigned char *valueDer = NULL_PTR;
  unsigned int valueDerLen = 0;
  
  RSA_PrintBuf ("Unrecognized Attribute Type", type, typeLen);

  status = C_GetAttributeValueCount (attribObj, type, typeLen, &valueCount);
  if (status != 0)
    goto CLEANUP;

  for (i = 0; i < valueCount; i++) {
    status = C_GetAttributeValueDER (attribObj, type, typeLen, i, &valueDer,
                                     &valueDerLen);
    if (status != 0)
      goto CLEANUP;

    RSA_PrintMessage ("--BER-encoded value #%i (%u bytes)\n", i+1,
                      valueDerLen);
    RSA_PrintBuf (NULL, valueDer, valueDerLen);
  }

CLEANUP:
  return status;
}  /* end PrintUnrecoginzedAttribute */

int RSA_GetAttrObjEntryPromptFn
   (unsigned char *attribType, unsigned int attribTypeLen,
    int (**promptFn) (ATTRIBUTES_OBJ, unsigned char *, unsigned int))
{
  int status = 0, i = 0;
  *promptFn = NULL;

  InitAttrTable ();

  for (i = 0; i < RSA_DEMO_ATTR_COUNT; i++)
    if (attribTypeLen == RSA_DEMO_ATTR_TABLE[i].val.atEntry.at.len &&
        T_memcmp (attribType, RSA_DEMO_ATTR_TABLE[i].val.atEntry.at.data,
                  RSA_DEMO_ATTR_TABLE[i].val.atEntry.at.len) == 0) {
      *promptFn = RSA_DEMO_ATTR_TABLE[i].val.atEntry.prompt;
      break;
    }

  if (*promptFn == NULL)
    status = RSA_DEMO_E_NOT_FOUND;

  return status;
}  /* end RSA_GetAttrObjEntryPromptFn */

int RSA_PrintAttributesObject (char *label, ATTRIBUTES_OBJ attribObj)
{
  int status = 0;

  unsigned int attribCount = 0, index = 0;

  unsigned char *attribType = NULL_PTR;
  unsigned int attribTypeLen = 0;

  int (*PrintAttribute) (ATTRIBUTES_OBJ attribObj, unsigned char *type,
                         unsigned int typeLen) = NULL;

  if (label != NULL)
    RSA_PrintMessage ("%s\n", label);

  status = C_GetAttributeTypeCount (attribObj, &attribCount);
  if (status != 0)
    goto CLEANUP;

  for (index = 0; index < attribCount; index++) {
    status = C_GetAttributeType (attribObj, index, &attribType,
                                 &attribTypeLen);
    if (status != 0)
      goto CLEANUP;

    status = RSA_GetAttrObjEntryPrintFn (attribType, attribTypeLen,
                                         &PrintAttribute);
    if (status == RSA_DEMO_E_NOT_FOUND)
      status = PrintUnrecognizedAttribute (attribObj, attribType,
                                           attribTypeLen);
    else if (status == 0)
      status = (*PrintAttribute) (attribObj, attribType, attribTypeLen);

    if (status != 0)
      goto CLEANUP;
  }

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

  return status;
}  /* end RSA_PrintAttributesObject */

int RSA_GetInputToAttributesObject (ATTRIBUTES_OBJ attribObj)
{
  int status = 0;

  unsigned char *attributeType = NULL;
  unsigned int attributeTypeLen = 0;

  int (*ValuePrompt) (ATTRIBUTES_OBJ attribObj, unsigned char *type,
                      unsigned int typeLen) = NULL;
  
  /*  Keep going until user enters a blank (just hits return in response to the
   *  prompt).
   */
  for (;;) {
    /*  Prompt user for attribute type  */
    status = RSA_AttrObjEntryTypePrompt (&attributeType, &attributeTypeLen);
    if (status == RSA_DEMO_E_CANCEL) {
      status = 0;
      break;
    }
    else if (status != 0)
      goto CLEANUP;
    
    status = RSA_GetAttrObjEntryPromptFn (attributeType, attributeTypeLen,
                                          &ValuePrompt);
    if (status != 0)
      goto CLEANUP;

    status = (*ValuePrompt) (attribObj, attributeType, attributeTypeLen);
    if (status != 0 && status != RSA_DEMO_E_CANCEL)
      goto CLEANUP;
  }
  
CLEANUP:
  if (status != 0)
    RSA_PrintError ("RSA_GetInputToAttributesObject", status);

  return status;
}  /* end RSA_GetInputToAttributesObject */

int RSA_GetAttributesObject (ATTRIBUTES_OBJ attribObj)
{
  int status = 0;
  unsigned char *attribDer = NULL_PTR;
  unsigned int attribDerLen = 0;

  RSA_PrintMessage
  ("Enter name of file containing attributes object binary\n");
  
  status = RSA_GetFileToAllocBuffer (&attribDer, &attribDerLen,
                                     "(blank to create a new one)");
  if (status == RSA_DEMO_E_CANCEL) {
    status = RSA_GetInputToAttributesObject (attribObj);
    /* whatever happens, we're done here */
    goto CLEANUP;
  }
  if (status != 0)
    goto CLEANUP;

  status = C_SetAttributesBER (attribObj, attribDer, attribDerLen);
  if (status != 0)
    goto CLEANUP;
  
CLEANUP:
  if (status != 0)
    RSA_PrintError ("RSA_GetAttributesObject", status);

  T_free (attribDer);
  
  return status;
}  /* end RSA_GetAttributesObject */

static int PrintStringAttribute (ATTRIBUTES_OBJ attribObj, unsigned char *type,
                                 unsigned int typeLen)
{
  int status = 0;

  char *description = NULL, *valueTagString = NULL;
  unsigned int valueCount = 0, i = 0;
  int valueTag = 0;
  unsigned char *value = NULL_PTR;
  unsigned int valueLen = 0;

  status = RSA_GetAttrObjEntryTypeDesc (type, typeLen, &description);
  if (status != 0)
    goto CLEANUP;

  RSA_PrintMessage ("%s\n", description);

  status = C_GetAttributeValueCount (attribObj, type, typeLen, &valueCount);
  if (status != 0)
    goto CLEANUP;

  for (i = 0; i < valueCount; i++) {
    status = C_GetStringAttribute (attribObj, type, typeLen, i, &valueTag,
                                   &value, &valueLen);
    if (status != 0)
      goto CLEANUP;

    status = RSA_GetValueTagDesc (valueTag, &valueTagString);
    if (status == RSA_DEMO_E_NOT_FOUND) {
      RSA_PrintMessage ("Unrecognized Attribute Value Tag = %i\n", valueTag);
      status = 0;
    }
    else if (status != 0)
      goto CLEANUP;

    if (valueTagString != NULL) {
      RSA_PrintMessage ("Value #%u, %s (%u bytes):\n", i+1, valueTagString,
                        valueLen);
      RSA_PrintBuf (NULL, value, valueLen);
    }
    else {
      RSA_PrintMessage ("Value #%u (%u bytes):\n", i+1, valueLen);
      RSA_PrintBuf (NULL, value, valueLen);
    }
  }

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

  return status;
}  /* end PrintStringAttribute */

static int StringAttributePrompt (ATTRIBUTES_OBJ attribObj,
                                  unsigned char *type, unsigned int typeLen)
{
  int status = 0, valueTag = 0;
  char valueString [RSA_DEMO_MAX_LINE_LEN];

  status = RSA_ValueTagPrompt (&valueTag);
  if (status != 0)
    goto CLEANUP;

  status = RSA_GetCommand (valueString, sizeof (valueString),
                           "Enter attribute value string");
  if (status != 0)
    goto CLEANUP;

  status = C_AddStringAttribute (attribObj, type, typeLen, valueTag,
                                 (unsigned char *)valueString,
                                 T_strlen (valueString));
  if (status == E_ATTRIBUTE_TAG) {
    RSA_PrintError ("The string value tag you selected is not compatible \
with the attribute\ntype.  Refer to the LRM for compatible types.", 0);
    RSA_PrintMessage ("Try again\n");
    status = 0;
  }
  else if (status != 0)
    goto CLEANUP;
  
CLEANUP:
  if (status != 0)
    RSA_PrintError ("StringAttributePrompt", status);
  
  return status;
}  /* end StringAttributePrompt */

static int PrintSigningTime (ATTRIBUTES_OBJ attribObj, unsigned char *type,
                             unsigned int typeLen)
{
  int status = 0;
  UINT4 signingTime = 0;

  UNUSED_ARG (type);
  UNUSED_ARG (typeLen);

  status = C_GetSigningTimeAttribute (attribObj, &signingTime);
  if (status == 0)
    RSA_PrintUint4Time ("Signing Time", signingTime);
  
  return status;
}  /* end PrintSigningTime */

static int SigningTimePrompt (ATTRIBUTES_OBJ attribObj, unsigned char *type,
                              unsigned int typeLen)
{
  int status = 0;
  UINT4 signingTime = 0;

  UNUSED_ARG (type);
  UNUSED_ARG (typeLen);

  status = RSA_GetInputToUint4Time (&signingTime, "Enter Signing Time");
  if (status != 0)
    goto CLEANUP;

  status = C_SetSigningTimeAttribute (attribObj, signingTime);
  
CLEANUP:
  return status;
}  /* end SigningTimePrompt */

static int PrintChallengePassword (ATTRIBUTES_OBJ attribObj,
                                   unsigned char *type, unsigned int typeLen)
{
  int status = 0, valueTag = 0;
  char *valueTagString = NULL;
  unsigned char *password = NULL_PTR;
  unsigned int passwordLen = 0;

  UNUSED_ARG (type);
  UNUSED_ARG (typeLen);

  status = C_GetChallengePasswordAttribute (attribObj, &valueTag, &password,
                                            &passwordLen);
  if (status != 0)
    goto CLEANUP;

  status = RSA_GetValueTagDesc (valueTag, &valueTagString);
  if (status == RSA_DEMO_E_NOT_FOUND) {
    RSA_PrintMessage ("Unrecognized Attribute Value Tag = %i\n", valueTag);
    status = 0;
  }
  else if (status != 0)
    goto CLEANUP;

  if (valueTagString != NULL) {
    RSA_PrintMessage ("Challenge Password, %s (%u bytes):\n", valueTagString,
                      passwordLen);
    RSA_PrintBuf (NULL, password, passwordLen);
  }
  else
    RSA_PrintBuf ("Challenge Password", password, passwordLen);

CLEANUP:
  return status;
}  /* end PrintChallengePassword */

static int ChallengePasswordPrompt (ATTRIBUTES_OBJ attribObj,
                                    unsigned char *type, unsigned int typeLen)
{
  int status = 0, valueTag = 0;
  unsigned char valueString [RSA_DEMO_MAX_LINE_LEN];

  UNUSED_ARG (type);
  UNUSED_ARG (typeLen);

  status = RSA_ValueTagPrompt (&valueTag);
  if (status != 0)
    goto CLEANUP;

  status = RSA_GetCommand ((char *)valueString, sizeof (valueString),
                           "Enter challenge password");
  if (status != 0)
    goto CLEANUP;

  status = C_SetChallengePasswordAttribute (attribObj, valueTag, valueString,
                                            T_strlen ((char *)valueString));
  if (status == E_ATTRIBUTE_TAG) {
    RSA_PrintError ("The string value tag you selected is not compatible \
with the attribute\ntype.  Refer to the LRM for compatible types.", 0);
    RSA_PrintMessage ("Try again.");
    status = 0;
  }
  
CLEANUP:
  return status;
}  /* end ChallengePasswordPrompt */

static int PrintPostalAddress (ATTRIBUTES_OBJ attribObj, unsigned char *type,
                               unsigned int typeLen)
{
  int status = 0;

  POSTAL_ADDRESS postalAddress;  
  unsigned int valueCount = 0, i = 0;
  unsigned int j = 0;

  char *tagString = NULL;

  UNUSED_ARG (type);
  UNUSED_ARG (typeLen);

  status = C_GetPostalAddressValueCount (&valueCount, attribObj);
  if (status != 0)
    goto CLEANUP;
  
  for (i = 0; i < valueCount; i++) {
    RSA_PrintMessage ("Postal Address Attribute #%u\n", i+1);
    status = C_GetPostalAddressValue (&postalAddress, attribObj, i);
    if (status != 0)
      goto CLEANUP;

    for (j = 0; j < postalAddress.count; j++) {
      RSA_PrintMessage ("  Line #%u,", j+1);
      status = RSA_GetValueTagDesc (postalAddress.lines[j].tag, &tagString);
      if (status == RSA_DEMO_E_NOT_FOUND) {
        RSA_PrintMessage (" Unrecognized Value Tag = %i\n",
                          postalAddress.lines[j].tag);
        status = 0;
      }
      else if (status != 0)
        goto CLEANUP;

      RSA_PrintMessage ("%s (%u bytes)\n", tagString,
                        postalAddress.lines[j].valueLen);
      RSA_PrintBuf (NULL, postalAddress.lines[j].value,
                    postalAddress.lines[j].valueLen);
    }
  }

CLEANUP:
  return status;
}  /* end PrintPostalAddress */

static int PostalAddressPrompt (ATTRIBUTES_OBJ attribObj, unsigned char *type,
                                unsigned int typeLen)
{
  int status = 0, valueTag = 0;
  unsigned char valueString[RSA_DEMO_MAX_LINE_LEN];
  unsigned int i = 0;

  POSTAL_ADDRESS postalAddress;

  UNUSED_ARG (type);
  UNUSED_ARG (typeLen);

  for (i = 0; i < MAX_ADDRESS_LINE_COUNT; i++) {
    RSA_PrintMessage ("Postal Address, line #%u\n", i+1);
    status = RSA_ValueTagPrompt (&valueTag);
    if (status != 0)
      goto CLEANUP;

    status = RSA_GetCommand ((char *)valueString, sizeof (valueString),
                             "Enter value");
    if (status != 0)
      goto CLEANUP;

    postalAddress.count = i+1;
    postalAddress.lines[i].tag = valueTag;
    postalAddress.lines[i].value = valueString;
    postalAddress.lines[i].valueLen = T_strlen ((char *)valueString);
  }

  status = C_AddPostalAddressValue (attribObj, &postalAddress);

CLEANUP:
  return status;
}  /* end PostalAddressPrompt */

static int PrintExtensionsAttribute (ATTRIBUTES_OBJ attribObj,
                                     unsigned char *type,
                                     unsigned int typeLen)
{
  int status = 0;
  unsigned char *valueDer = NULL;
  unsigned int valueDerLen = 0, i = 0, valueCount = 0;

  status = C_GetAttributeValueCount (attribObj, type, typeLen, &valueCount);
  if (status != 0)
    goto CLEANUP;  

  /*  ...there should only be one value, but just in case  */
  for (i = 0; i < valueCount; i++) {
    status = C_GetAttributeValueDER (attribObj, type, typeLen, i, &valueDer,
                                     &valueDerLen);
    if (status != 0)
      goto CLEANUP;

    RSA_PrintBuf ("BER-encoded extensions", valueDer, valueDerLen);
  }

CLEANUP:
  if (status != 0)
    RSA_PrintError ("PrintExtensionsAttribute", status);
  
  return status;
}  /* end PrintExtensionsAttribute */

static int ExtensionsAttributePrompt (ATTRIBUTES_OBJ attribObj,
                                      unsigned char *type,
                                      unsigned int typeLen)
{
  int status = 0;

  CERTC_CTX ctx = NULL;
  EXTENSIONS_OBJ extenObj = NULL;

  UNUSED_ARG (type);
  UNUSED_ARG (typeLen);

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

  status = RSA_GetFileToExtensionsObject (ctx, &extenObj);
  if (status != 0)
    goto CLEANUP;

  status = C_GetAttributeInExtensionsObj (extenObj, attribObj);
  if (status != 0)
    goto CLEANUP;
  
CLEANUP:
  if (status != 0)
    RSA_PrintError ("ExtensionsAttributePrompt", status);

  C_DestroyExtensionsObject (&extenObj);
  C_FinalizeCertC (&ctx);

  return status;
} /* end ExtensionsAttributePrompt */

static void InitAttrTable () {
  int i = 0, j = 0;
  static int flag = 0;

  if (flag)
    return;
  flag = 1;

  RSA_DEMO_ATTR_TABLE[0].description = "Signing Time";
  RSA_DEMO_ATTR_TABLE[0].val.atEntry.at.data = AT_SIGNING_TIME;
  RSA_DEMO_ATTR_TABLE[0].val.atEntry.at.len = AT_SIGNING_TIME_LEN;
  RSA_DEMO_ATTR_TABLE[0].val.atEntry.print = PrintSigningTime;
  RSA_DEMO_ATTR_TABLE[0].val.atEntry.prompt = SigningTimePrompt;
  RSA_DEMO_ATTR_TABLE[1].description = "Challenge Password";
  RSA_DEMO_ATTR_TABLE[1].val.atEntry.at.data = AT_CHALLENGE_PASSWORD;
  RSA_DEMO_ATTR_TABLE[1].val.atEntry.at.len = AT_CHALLENGE_PASSWORD_LEN;
  RSA_DEMO_ATTR_TABLE[1].val.atEntry.print = PrintChallengePassword;
  RSA_DEMO_ATTR_TABLE[1].val.atEntry.prompt = ChallengePasswordPrompt;
  RSA_DEMO_ATTR_TABLE[2].description = "Postal Address";
  RSA_DEMO_ATTR_TABLE[2].val.atEntry.at.data = AT_POSTAL_ADDRESS;
  RSA_DEMO_ATTR_TABLE[2].val.atEntry.at.len = AT_POSTAL_ADDRESS_LEN;
  RSA_DEMO_ATTR_TABLE[2].val.atEntry.print = PrintPostalAddress;
  RSA_DEMO_ATTR_TABLE[2].val.atEntry.prompt = PostalAddressPrompt;
  RSA_DEMO_ATTR_TABLE[3].description = "Extensions Attribute";
  RSA_DEMO_ATTR_TABLE[3].val.atEntry.at.data = AT_X509_V3_EXTENSIONS;
  RSA_DEMO_ATTR_TABLE[3].val.atEntry.at.len = AT_X509_V3_EXTENSIONS_LEN;
  RSA_DEMO_ATTR_TABLE[3].val.atEntry.print = PrintExtensionsAttribute;
  RSA_DEMO_ATTR_TABLE[3].val.atEntry.prompt = ExtensionsAttributePrompt;
  InitAtTable ();
  for (i = RSA_DEMO_ATTR_COUNT - RSA_DEMO_AT_COUNT, j = 0;
       i < RSA_DEMO_ATTR_COUNT; i++, j++) {
    RSA_DEMO_ATTR_TABLE[i].description = RSA_DEMO_AT_TABLE[j].description;
    RSA_DEMO_ATTR_TABLE[i].val.atEntry.at.data =
      RSA_DEMO_AT_TABLE[j].val.at.data;
    RSA_DEMO_ATTR_TABLE[i].val.atEntry.at.len =
      RSA_DEMO_AT_TABLE[j].val.at.len;
    RSA_DEMO_ATTR_TABLE[i].val.atEntry.print = PrintStringAttribute;
    RSA_DEMO_ATTR_TABLE[i].val.atEntry.prompt = StringAttributePrompt;
  }
}  /* end InitAttrTable */

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