RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

saltname.c

Overrides default handles for the subject alternative name extension

/* $Id: saltname.c,v 1.3 2004/03/02 05:18:35 gsingh Exp $ */
/* saltname.c
** Copyright (c) 2001-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.
**
** Override the default handler for the subject alt name extension so
** that it does not return a non-zero error code when encountering a bad
** encoding of a GeneralName.
*/

#include "certc.h"
#include "demoutil.h"                   /* for RSA_* demo utility functions */
#include "filelog.h"

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

  CERT_OBJ certObj = NULL;
  CERT_FIELDS certFields;
  ITEM certBer = {NULL, 0};

  CERTC_CTX ctx = NULL;
  EXTENSION_TYPE_INFO subAltNameTypeInfo, defaultTypeInfo;

  EXTENSIONS_OBJ extensions = NULL;
  EXTENSION_INFO subAltNameInfo;
  ITEM *subAltNameValue = NULL;
  unsigned int subAltNameIndex = 0, i;

  LIST_OBJ altNameList = NULL;
  ALTERNATE_NAME *altNameValue = NULL;
  LIST_OBJ_ENTRY_HANDLER altNameHandler;
  int (*ParseAltName) (LIST_OBJ valueList, unsigned char *encodedValue,
                       unsigned int encodedValueLen,
                       LIST_OBJ_ENTRY_HANDLER *addValueHandler);

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

  /* Initialize demoutil options */
  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

  /* In a given CERTC_CTX, override the handler for the subject alt name
     extension (which works with an ALTERNATE_NAME structure) with the
     default hander (which stores the BER-encoded value in an ITEM). */
  status = C_GetExtensionTypeInfo (ctx, ET_SUBJECT_ALTNAME,
                                   ET_SUBJECT_ALTNAME_LEN,
                                   &subAltNameTypeInfo);
  if (status != 0)
    goto CLEANUP;

  altNameHandler.AllocAndCopy = subAltNameTypeInfo.handler.AllocAndCopy;
  altNameHandler.Destructor = subAltNameTypeInfo.handler.Destructor;
  ParseAltName = subAltNameTypeInfo.handler.SetEncodedValue;

  status = C_GetExtensionTypeInfo (ctx, ET_UNKNOWN_TYPE, ET_UNKNOWN_TYPE_LEN,
                                   &defaultTypeInfo);
  if (status != 0)
    goto CLEANUP;

  subAltNameTypeInfo.handler = defaultTypeInfo.handler;

  status = C_RegisterExtensionType (ctx, &subAltNameTypeInfo);
  if (status != 0)
    goto CLEANUP;

  status = C_CreateCertObject (&certObj, ctx);
  if (status != 0)
    goto CLEANUP;

  status = RSA_GetFileToAllocBuffer
             (&certBer.data, &certBer.len,
              "Enter name of file containing cert binary");
  if (status != 0)
    goto CLEANUP;

  status = C_SetCertBER (certObj, certBer.data, certBer.len);
  if (status != 0)
    goto CLEANUP;

  RSA_PrintMessage ("C_SetCertBER successful!\n");

  status = C_GetCertFields (certObj, &certFields);
  if (status != 0)
    goto CLEANUP;

  extensions = certFields.certExtensions;

  RSA_PrintMessage ("Checking for subject alt name extension...\n");
  status = C_FindExtensionByType (extensions, ET_SUBJECT_ALTNAME,
                                  ET_SUBJECT_ALTNAME_LEN, &subAltNameIndex);
  if (status == E_NOT_FOUND) {
    RSA_PrintMessage ("No subject alt name extension present.\n");
    status = 0;
  } else if (status == 0) {
    status = C_GetExtensionInfo (extensions, subAltNameIndex,
                                 &subAltNameInfo);
    if (status != 0)
      goto CLEANUP;

    RSA_PrintMessage ("%d subject alternate name values present.\n",
                      subAltNameInfo.valueCount);
    for (i = 0; i < subAltNameInfo.valueCount; i++) {
      status = C_GetExtensionValue (extensions, subAltNameIndex, i,
                                    (POINTER *)&subAltNameValue);
      if (status != 0)
        goto CLEANUP;

      RSA_PrintMessage ("Value #%d (%d bytes):\n", i+1, subAltNameValue->len);
      RSA_PrintBuf (NULL, subAltNameValue->data, subAltNameValue->len);

      /* Attempt to put each alternate name value into an ALTERNATE_NAME */
      status = C_CreateListObject (&altNameList);
      if (status != 0)
        goto CLEANUP;

      status = ParseAltName (altNameList, subAltNameValue->data,
                             subAltNameValue->len, &altNameHandler);
      if (status != 0) {
        RSA_PrintMessage ("Unable to parse Subject Alt Name Value.\n");
        if (subAltNameInfo.criticalFlag == NON_CRITICAL)
          status = 0;
      } else {
        /* There is always only at most one entry in the list */
        status = C_GetListObjectEntry (altNameList, 0,
                                       (POINTER