RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

demo.c

Contains main function, menu, and other user prompts demo.c uses the standard C library functions such as printf(), fopen(), etc

/* $Id: demo.c,v 1.3 2004/03/02 05:18:34 gsingh Exp $ */
/* demo.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 "demo.h"
#include "dmenu.h"
#include "dchooser.h"
#include "genreq.h"
#include "fulfill.h"
#include "dcrl.h" 
#include "userextn.h"
#include "dutil.h"
#include "surrende.h" 
#include "inoutcl.h"

#ifndef _BCERT_API_
#include "certc.h"
#include "rsacsp.h"
#include "textsurr.h"
#endif /* _BCERT_API_ */

#ifdef TEST_MEMORY_LEAK
#include "memlog.h"
#endif


#define RANDOM_BYTES_NEEDED 256

static void DoFulfillCertRequest PROTO_LIST ((SESSION_CTX *));
static void DoGenerateCertRequest PROTO_LIST ((SESSION_CTX *));
static void DoRevokeCert PROTO_LIST ((SESSION_CTX *));
#ifdef _BCERT_API_
static int InitializeApplContext PROTO_LIST ((SESSION_CTX *));
static int InitializeRandomObject PROTO_LIST 
  ((B_ALGORITHM_OBJ *, A_SURRENDER_CTX *));
#endif /* _BCERT_API_ */
static int InitializeSessionContext PROTO_LIST ((SESSION_CTX *));
static void FinalizeSessionContext PROTO_LIST ((SESSION_CTX *));

/* Certificate authority's public key */
unsigned char ISSUER_PUBLIC_KEY[94] = {
  0x30, 0x5C, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
  0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4B, 0x00, 0x30, 0x48, 0x02, 0x41,
  0x00, 0xCC, 0xBC, 0x41, 0xC5, 0xBB, 0x44, 0xCA, 0xC1, 0xE2, 0xC4, 0xDD,
  0x43, 0xC3, 0x66, 0x6F, 0x60, 0xC5, 0x98, 0x99, 0xA4, 0x5A, 0x7F, 0x9E,
  0x97, 0xE3, 0x5D, 0x79, 0xA9, 0x88, 0x0C, 0x49, 0x57, 0xFE, 0xAC, 0x3D,
  0x98, 0x84, 0x2E, 0xE3, 0x13, 0x63, 0xD4, 0x57, 0xDE, 0xA5, 0xF2, 0x4D,
  0xC7, 0x33, 0xEF, 0x03, 0x43, 0xAD, 0x30, 0xA8, 0x72, 0xEB, 0xE6, 0xE4,
  0xAE, 0x5C, 0x8C, 0x11, 0x4F, 0x02, 0x03, 0x01, 0x00, 0x01
};
    
/* Certificate authority's private key */
unsigned char ISSUER_PRIVATE_KEY[344] = { 
  0x30, 0x82, 0x01, 0x54, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A,
  0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
  0x01, 0x3E, 0x30, 0x82, 0x01, 0x3A, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
  0xCC, 0xBC, 0x41, 0xC5, 0xBB, 0x44, 0xCA, 0xC1, 0xE2, 0xC4, 0xDD, 0x43,
  0xC3, 0x66, 0x6F, 0x60, 0xC5, 0x98, 0x99, 0xA4, 0x5A, 0x7F, 0x9E, 0x97,
  0xE3, 0x5D, 0x79, 0xA9, 0x88, 0x0C, 0x49, 0x57, 0xFE, 0xAC, 0x3D, 0x98,
  0x84, 0x2E, 0xE3, 0x13, 0x63, 0xD4, 0x57, 0xDE, 0xA5, 0xF2, 0x4D, 0xC7,
  0x33, 0xEF, 0x03, 0x43, 0xAD, 0x30, 0xA8, 0x72, 0xEB, 0xE6, 0xE4, 0xAE,
  0x5C, 0x8C, 0x11, 0x4F, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x25,
  0x30, 0x0C, 0xC2, 0x5D, 0xC1, 0xA1, 0x12, 0x96, 0x9E, 0x2B, 0x92, 0xA3,
  0x6B, 0x77, 0xCF, 0x9C, 0x14, 0x9B, 0xD3, 0xBE, 0x9C, 0x6F, 0xB2, 0x27,
  0x1A, 0x53, 0x7E, 0xF7, 0xB7, 0x43, 0x9A, 0xE4, 0xEF, 0xC4, 0x71, 0xAB,
  0x30, 0x8D, 0xEB, 0xBB, 0xE3, 0xFE, 0x72, 0x1E, 0x1E, 0xA1, 0xFB, 0x0D,
  0x1D, 0x57, 0x2D, 0xBF, 0x5D, 0x43, 0xD6, 0xF8, 0x92, 0x29, 0xBB, 0x7C,
  0xE9, 0x50, 0x01, 0x02, 0x21, 0x00, 0xEC, 0xE7, 0xB9, 0xDE, 0x69, 0xCE,
  0xD0, 0x96, 0x63, 0xD2, 0xE3, 0x9C, 0x78, 0x1D, 0xFD, 0xC7, 0xC8, 0x66,
  0xEA, 0x67, 0x51, 0xB6, 0x3A, 0x1C, 0x5C, 0x37, 0x9D, 0x5E, 0xEC, 0x16,
  0x58, 0xBF, 0x02, 0x21, 0x00, 0xDD, 0x3C, 0xBE, 0x30, 0xD2, 0x11, 0xC4,
  0xCD, 0xFE, 0x4A, 0x85, 0xAC, 0xEB, 0x67, 0x94, 0x43, 0x39, 0x75, 0x6C,
  0x94, 0x4D, 0x7A, 0x5C, 0xB2, 0xDA, 0x7F, 0xBE, 0xC2, 0x38, 0x9D, 0x5B,
  0x71, 0x02, 0x20, 0x24, 0xF8, 0x08, 0x4E, 0x47, 0xEE, 0xA9, 0x28, 0x3E,
  0xCD, 0xA3, 0x0D, 0x40, 0xC5, 0x55, 0x5B, 0xFE, 0xCE, 0xE8, 0x97, 0x54,
  0xED, 0xFD, 0xE5, 0x7D, 0x12, 0x84, 0xB1, 0x52, 0x60, 0x2E, 0x5B, 0x02,
  0x20, 0x58, 0xB6, 0x2D, 0xB1, 0x57, 0xDA, 0xC6, 0x26, 0xAF, 0x8B, 0xE4,
  0x54, 0x35, 0x44, 0xA0, 0x5F, 0xE0, 0x5F, 0x64, 0x7D, 0x87, 0x1F, 0xC4,
  0xA1, 0xF7, 0x19, 0x78, 0x3D, 0x5B, 0x04, 0x46, 0x11, 0x02, 0x21, 0x00,
  0xA8, 0x26, 0x6E, 0xF2, 0x09, 0x6E, 0x09, 0x0C, 0xC4, 0x1E, 0x3A, 0xFC,
  0xB6, 0x46, 0xC6, 0x2A, 0x07, 0xF9, 0x8C, 0x8B, 0x7A, 0x15, 0xB8, 0xCC,
  0x8F, 0x06, 0x67, 0xEB, 0x51, 0xBB, 0x50, 0x08 
};

Entry MAIN_MENU[] = {  
  {"F - Fulfill PKCS Certificate Request", DoFulfillCertRequest},  
  {"G - Generate PKCS Certificate Request", DoGenerateCertRequest},
  {"R - Revoke Certificate", DoRevokeCert},
  {0, 0}
};

int main (argc, argv)
int argc;
char *argv[];
{  
   SESSION_CTX sessionContext;
   char buffer[50];
   int status;

#ifdef TEST_MEMORY_LEAK
   MemoryLogSwitch (MEMORY_LOG_ON);
#endif

   T_memset ((POINTER)&sessionContext, 0, sizeof (sessionContext));
   OpenIOContextCL (&sessionContext.ioContext, argc, argv);
   
   if ((status = InitializeSessionContext (&sessionContext)) == 0) {
#ifdef _BCERT_API_
     sprintf (buffer, "\nBCERT Demo %s", BCERT_VERSION);
#else
     sprintf (buffer, "\nCert-C Demo 1.0");
#endif /* _BCERT_API_ */
     PrintMessage (buffer, 0, IO_CTX_PROMPT, &sessionContext.ioContext);
     Run (MAIN_MENU, &sessionContext);
   }
   else
     PrintMessage
       ("Abort: Failed to initialize session context", 0, status, 
        &sessionContext.ioContext);
   FinalizeSessionContext (&sessionContext);
   CloseIOContextCL (&sessionContext.ioContext);
   
#ifdef TEST_MEMORY_LEAK
   MemoryLogSwitch (MEMORY_LOG_OFF);
#endif

   return status;
}                                             

static int InitializeSessionContext (sessionContext)
SESSION_CTX *sessionContext;
{ 
  NAME_OBJ issuerName = (NAME_OBJ)NULL_PTR;
  int status;

#ifndef _BCERT_API_

#define SP_COUNT 2

  SERVICE_HANDLER spTable[SP_COUNT] = {
    {SPT_CRYPTO, "Crypto Provider", S_InitializeDefaultCSP},
    {SPT_SURRENDER, "Surrender Provider", S_InitializeTextSurrender}
  };
  POINTER spParams[SP_COUNT] = {
    NULL, NULL
  };
#endif /* _BCERT_API_ */
  
  do { 
    /* Create an issuer name */
    if ((status = C_CreateNameObject (&issuerName)) != 0)
      break;
    if ((status = MakeNameObject 
         (issuerName, (unsigned char *)NULL_PTR, 0)) != 0)
      break;
    
    /* Create a new crl object */
#ifdef _BCERT_API_
    if ((status = C_CreateCRLObject 
         (&sessionContext->crlObject, sessionContext->applContext)) != 0)
      break;
#else
    if ((status = C_InitializeCertC 
                  (spTable, spParams, SP_COUNT,
                   &sessionContext->certcContext)) != 0)
      break;

    if ((status = C_CreateCRLObject 
         (&sessionContext->crlObject, sessionContext->certcContext)) != 0)
      break;
#endif /* _BCERT_API_ */

    if ((status = C_PrepareUnsignedCRLForIssuer
         (sessionContext->crlObject, issuerName)) != 0)
      break;
      
#ifdef _BCERT_API_
    /* Initialize the application context for use with
         x.509 v3 user-defined extension later */  
    if ((status = InitializeApplContext (sessionContext)) != 0)
      break; 
      
    /* Initialize surrender context */
    InitWaitingSurrenderContext (sessionContext);  
      
    status = InitializeRandomObject 
      (&sessionContext->randomObject, &sessionContext->surrender);
#else
    status = RegisterUserDefinedExtension (sessionContext->certcContext);
#endif /* _BCERT_API_ */
  } while (0);
  C_DestroyNameObject (&issuerName);
  return (status);
}                                          

#ifdef _BCERT_API_
static int InitializeApplContext (sessionContext)
SESSION_CTX *sessionContext;
{
  int status;
  
  /* Get an application context */
  if ((status = C_InitializeApplContext (&sessionContext->applContext)) != 0)
    return (status);
  
  /* Register a user-defined extension */
  return (RegisterUserDefinedExtension (sessionContext->applContext));
}
#endif /* _BCERT_API_ */

static void FinalizeSessionContext (sessionContext)
SESSION_CTX *sessionContext;
{  
  C_DestroyCRLObject (&sessionContext->crlObject);

#ifdef _BCERT_API_
  /* Unregister a registered user-defined extension type */
  C_UnregisterExtensionType
    (sessionContext->applContext, USER_DEFINED_EXTENSION,
     USER_DEFINED_EXTENSION_LEN);
  
  C_FinalizeApplContext (&sessionContext->applContext);
  B_DestroyAlgorithmObject (&sessionContext->randomObject);
#else
  /* Unregister a registered user-defined extension type */
  C_UnregisterExtensionType
    (sessionContext->certcContext, USER_DEFINED_EXTENSION,
     USER_DEFINED_EXTENSION_LEN);

  C_FinalizeCertC (&sessionContext->certcContext);
#endif /* _BCERT_API_ */
}

#ifdef _BCERT_API_
static int InitializeRandomObject (randomObject, surrender)
B_ALGORITHM_OBJ *randomObject;
A_SURRENDER_CTX *surrender;
{            
  unsigned char randomBlock [RANDOM_BYTES_NEEDED];                  
  int status;
  
  *randomObject = (B_ALGORITHM_OBJ)NULL_PTR;
  do {
    /* Create a BSAFE random object */
    if ((status = B_CreateAlgorithmObject (randomObject)) != 0)
      break;
    if ((status = B_SetAlgorithmInfo
         (*randomObject, AI_MD5Random, NULL_PTR)) != 0)
      break;
    if ((status = B_RandomInit
         (*randomObject, DEMO_CHOOSER, surrender)) != 0)
      break;                      
      
    /* For demonstration purpose, we seed the random object with 
         256 bytes of 0's.  It is important for application to seed
         the random object with some real randomness, not with 0s as
         demonstrated here.
     */                            
    T_memset ((POINTER)randomBlock, 0, sizeof (randomBlock));
    if ((status = B_RandomUpdate
         (*randomObject, randomBlock, sizeof (randomBlock), surrender)) != 0)
      break;
  } while (0);
  if (status != 0)
    B_DestroyAlgorithmObject (randomObject);
  return (status);
}
#endif /* _BCERT_API_ */

static void DoRevokeCert (sessionContext)
SESSION_CTX *sessionContext;
{
  int status;
  
  if ((status = RevokeCert (sessionContext)) != 0)
    PrintMessage 
      ("Failed to revoke the certificate!", 0, status, 
       &sessionContext->ioContext);
  else
    PrintMessage 
      ("The certificate has been revoked!", 
       0, IO_CTX_PROMPT, &sessionContext->ioContext);
}

static void DoGenerateCertRequest (sessionContext)
SESSION_CTX *sessionContext;
{
  int status;

  if ((status = GenerateCertRequest (sessionContext)) != 0) {
    if (status != D_KEY_LEN) 
      PrintMessage
        ("Failed to generate the certificate request!", 0, status, 
         &sessionContext->ioContext);
    else
      PrintMessage
        ("Failed to generate the RSA key pair!", 0, status, 
         &sessionContext->ioContext);  
  }
  else
    PrintMessage 
      ("The certificate request has been generated successfully!", 
       0, IO_CTX_PROMPT, &sessionContext->ioContext);
}

static void DoFulfillCertRequest (sessionContext)
SESSION_CTX *sessionContext;
{
  int status;

  if ((status = FulfillCertRequest (sessionContext)) != 0)
    PrintMessage
      ("\nFailed to fulfill the certificate request!", 0, status, 
       &sessionContext->ioContext);
  else       
    PrintMessage ("The certificate request has been fulfilled!", 
       0, IO_CTX_PROMPT, &sessionContext->ioContext);
}

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