RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

userextn.c

Contain a user-defined extension, which may be added to an extensionsObject of type CRL_EXTENSIONS_OBJ or CRL_EXTENSIONS_ENTRY_OBJ. Also, they include callbacks for the extension handler. They demonstrate how an application may create its own user-defined extensions and incorporate them into the Cert-C extensions processing engine.

/* $Id: userextn.c,v 1.3 2004/03/02 05:18:34 gsingh Exp $ */
/* userextn.c
** Copyright (c) 1995-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.
*/

#include <stdio.h>
#include "aglobal.h"
#include "bsafe.h"
#include "bcert.h" 
#include "userextn.h"
#include "demo.h"

/* This module defines a user-defined extension type which can include
     all attributes that are supported by the BCERT library.  This extension
     can only have a unique value at any instance, and the critiality is 
     always CRITICAL.
 */ 
unsigned char USER_DEFINED_EXTENSION[] = "USER DEFINED EXTENSION TYPE";
unsigned int USER_DEFINED_EXTENSION_LEN = sizeof (USER_DEFINED_EXTENSION);

static int AllocAndCopy PROTO_LIST ((POINTER *, POINTER));
static void Destructor PROTO_LIST ((POINTER));
static int GetValueDER PROTO_LIST 
  ((LIST_OBJ, unsigned char **, unsigned int *));  
static int SetValueBER PROTO_LIST 
  ((LIST_OBJ, unsigned char *, unsigned int, LIST_OBJ_ENTRY_HANDLER *));


#if !GLOBAL_FUNCTION_POINTERS 
EXTENSION_HANDLER USER_DEFINED_HANDLER;
void C_SubjectDir_TemplateInit ()
{ 
  SUBJECT_DIR_HANDLER.AllocAndCopy = AllocAndCopy;
  SUBJECT_DIR_HANDLER.Destructor = Destructor;
  SUBJECT_DIR_HANDLER.GetEncodedValue = GetValueDER;
  SUBJECT_DIR_HANDLER.SetEncodedValue = SetValueBER;
}
#else
EXTENSION_HANDLER USER_DEFINED_HANDLER = { 
  AllocAndCopy, Destructor,  GetValueDER, SetValueBER
}; 
#endif

/* Register the USER_DEFINED_EXTENSION type and its handler. The extension is
     always critical.  Do not allow this handler to be overriden with a new 
     handler at C_CreateExtension() time.  This extension can have a unique 
     value at any instant, and is allowed to appear in both Certificate 
     extension and CRL extension.
 */
int RegisterUserDefinedExtension (applContext)
APPL_CTX applContext;
{ 
  EXTENSION_TYPE_INFO extTypeInfo; 
  
  extTypeInfo.type.data = USER_DEFINED_EXTENSION;
  extTypeInfo.type.len = USER_DEFINED_EXTENSION_LEN; 
  extTypeInfo.criticality = CRITICAL;             
  extTypeInfo.overrideCriticality = 0;
  extTypeInfo.authenObjects = 
    (UINT2)(CERT_EXTENSIONS_OBJ | CRL_EXTENSIONS_OBJ);
  extTypeInfo.uniqueValue = TRUE; 
  extTypeInfo.overrideHandler = 0;
  extTypeInfo.handler = USER_DEFINED_HANDLER;
  
  return (C_RegisterExtensionType (applContext, &extTypeInfo));
}

/* Return 0, E_ALLOC, E_DATA   
 */
static int AllocAndCopy  (newValue, value)
POINTER *newValue;
POINTER value;
{ 
  ATTRIBUTES_OBJ newExtension = (ATTRIBUTES_OBJ)NULL_PTR;
  ITEM der;
  int status;
  
  do {
    if ((status = C_CreateAttributesObject (&newExtension)) != 0)
      return (status);
    if ((status = C_GetAttributesDER (value, &der.data, &der.len)) != 0)
      GENERATE_BREAK (E_DATA);
    if ((status = C_SetAttributesBER (newExtension, der.data, der.len)) != 0)
      GENERATE_BREAK (E_DATA);
    *newValue = (POINTER)newExtension;
  } while (0);
  if (status != 0)
    C_DestroyAttributesObject (&newExtension);
  return (0);
} 

static void Destructor (value)
POINTER value;
{
  C_DestroyAttributesObject ((ATTRIBUTES_OBJ *)&value);
}

/* Return 0, E_ALLOC, E_DATA
   Can't get E_OVER_32K since this is a unique value extension unless 
     something is really wrong. 
   
   Note: It is IMPORTANT that GetValueDER callback allocates storages
     for the returned DER.  This storage will be destroyed by BCERT when the
     extension value is destroyed.  If no space is allocated by this routine,
     unpredictable errors may occur.
 */
static int GetValueDER (valueList, der, derLen)
LIST_OBJ valueList;
unsigned char **der;
unsigned int *derLen;
{
  ATTRIBUTES_OBJ value;
  ITEM valueDER;               
  int status;                  
      
  if (valueList == (LIST_OBJ)NULL_PTR)
    return (E_DATA);

  if ((status = C_GetListObjectEntry (valueList, 0, (POINTER *)&value)) != 0)
    return (E_DATA); 
  if ((status = C_GetAttributesDER
    (value, &valueDER.data, &valueDER.len)) != 0)
    return (E_DATA);
  if ((*der = T_malloc (*derLen = valueDER.len)) == NULL_PTR)
    return (E_ALLOC);
  T_memcpy ((POINTER)*der, (POINTER)valueDER.data, valueDER.len);
  return (0);
}

/* Decode and override the current value. 
   Return 0, E_ALLOC, E_BER_ENCODING, E_INVALID_HANDLER  
 */                
static int SetValueBER (valueList, ber, berLen, listObjEntryHandler)
LIST_OBJ valueList;
unsigned char *ber;
unsigned int berLen;
LIST_OBJ_ENTRY_HANDLER *listObjEntryHandler;           
{ 
  ATTRIBUTES_O