RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

dutil.c

Utilities to make Name objects for the default issuer and default subject names, to read from and write to files, and to convert error codes to error messages

/* $Id: dutil.c,v 1.4 2005/02/25 06:09:30 alockwoo Exp $ */
/* dutil.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 "demo.h"
#include "stdlibrf.h"
#include "bcert.h"
#include "dutil.h"
#include "simpleio.h"


/* Set nameObject with printable string.  Upon return, the nameObject
   is set to :
     C = US
     O = Example Issuer
     CN = "some common name as in commonName.  OK if commonName is NULL"
   Note:
   - if the commonName is passed in as NULL_PTR, then the nameObject only
     has 2 levels: Country (C) and Organization (O). This is used to set
     an issuer name "O = Example Issuer, C = US".
     
   - if the commonName is given, the nameObject will has 3 levels:
     Country (C), Organization (O), and the Common Name (CN).  This is used
     to set a subject name which subordinates to the issuer
      "O = Example Issuer, C = US" 
 */
int MakeNameObject (nameObject, commonName, commonNameLen)
NAME_OBJ nameObject;
unsigned char *commonName;
unsigned int commonNameLen;
{
  static char *organization = "Example Issuer";
  int status;

  /* Construct a name with the entered common name and the organization
       defined above.
   */
  do {
    if ((status = C_AddNameAVA
         (nameObject, AT_COUNTRY, AT_COUNTRY_LEN,
          VT_PRINTABLE_STRING, (unsigned char *)"US", COUNTRY_LEN, 1,
          (unsigned int *)NULL_PTR)) != 0)
      break;
    if ((status = C_AddNameAVA
         (nameObject, AT_ORGANIZATION,
          AT_ORGANIZATION_LEN, VT_PRINTABLE_STRING,
          (unsigned char *)organization, T_strlen (organization), 1,
          (unsigned int *)NULL_PTR)) != 0)
      break;
    if (commonNameLen && commonName != NULL_PTR) {
      if ((status = C_AddNameAVA
           (nameObject, AT_COMMON_NAME,
            AT_COMMON_NAME_LEN, VT_PRINTABLE_STRING,
            (unsigned char *)commonName, commonNameLen, 1,
            (unsigned int *)NULL_PTR)) != 0)
        break;
    }
  } while (0);
  return (status);
}

int WriteToFile (block, message, ioContext)
ITEM *block;
char *message;
IO_CTX_CL *ioContext;
{                 
  IO_CTX outputStream;
  char prompt[256], fileName[256];
  int status;
  
  InitSimpleIOContext (&outputStream, 1);
  sprintf
    (prompt, "\nPlease enter a file name to save the %s in: ", message); 
  GetCommandLine (fileName, sizeof(fileName), prompt, ioContext);

#ifdef _MAC_
    if ((status = OpenStream (&outputStream, fileName)) != 0)
    return (D_IO);
#else  
  if ((outputStream.handle = (POINTER)fopen (fileName, "wb")) == NULL_PTR)
    return (D_IO);
#endif  
    
  status = (outputStream.Write) (block->data, block->len, outputStream.handle);

#ifdef _MAC_
  CloseStream (&outputStream);
#else  
  fclose ((FILE *)outputStream.handle);
#endif  
  return (status);
}


int ReadFromFile (block, message, ioContext)
ITEM *block;
char *message; 
IO_CTX_CL *ioContext;
{
  IO_CTX inputStream;
  int status = 0;
  char buffer[80], fileName[80];
  unsigned int len;
  POINTER ptr;
    
  block->data = (unsigned char *)NULL_PTR;
  block->len = 0;
  InitSimpleIOContext (&inputStream, 1);
  
    
  sprintf (buffer, "Please enter the file name containing the %s: ", message);
  GetCommandLine (fileName, sizeof(fileName), buffer, ioContext);

#ifdef _MAC_  
  if ((status = OpenStream (&inputStream, filename)) != 0)
    return (D_IO);
#else  
  if ((inputStream.handle = (POINTER)fopen (fileName, "rb")) == NULL_PTR)
    return (D_IO);
#endif
  while (1) {
    status = (inputStream.Read) ((unsigned char *)buffer,
                                 &len, sizeof (buffer), inputStream.handle);
    if (status) {
      if (status == D_EOS)
        /* finished */
        status = 0;
      break;
    }
    
    if ((ptr = T_realloc ((POINTER)block->data, block->len + len)) ==
        NULL_PTR) {
      status = E_ALLOC;
      break;
    }
    block->data = (unsigned char *)ptr;

    T_memcpy ((POINTER)(block->data + block->len), (POINTER)buffer, len);
    block->len += len;
  }
  
  if (status) {
    T_free ((POINTER)block->data);
    block->data = (unsigned char *)NULL_PTR;
  }

#ifdef _MAC_  
  CloseStream (&inputStream);
#else
  fclose ((FILE *)inputStream.handle);
#endif    
  return (status);
}



static char *Demo_ErrorString (type)
int type;
{
  switch (type) {
    case D_EOS:
      return ("End of stream");
    case D_IO:
      return ("Fatal I/O error");  
    case D_CANCEL:
      return ("Operation is cancelled");
    case D_KEY_LEN:
      return ("Key length is invalid");
    default:
      return ((char *)NULL_PTR);
  }
}

static char *BCERT_ErrorString (type)
int type;
{
  switch (type) {
    case E_ALLOC:
      return ("Insufficient memory");
    case E_VERIFY_ASN_SIGNATURE:
      return ("Invalid signature on certificate or CRL");
    case E_COMPUTE_ASN_SIGNATURE:
      return ("Failed to create signature for certificate or CRL");
    case E_ATTRIBUTES_ENCODING:
      return ("Invalid attributes encoding"); 
    case E_ATTRIBUTES_OBJ:
      return ("Invalid attributes object");
    case E_ATTRIBUTE_TAG:
      return ("Invalid attribute value tag");
    case E_ATTRIBUTE_TYPE_LEN:
      return ("Unknown attribute type length");
    case E_ATTRIBUTE_TYPE:
      return ("Unknown attribute type");
    case E_ATTRIBUTE_TYPE_NOT_FOUND:
      return ("Attribute type can not be found");    
    case E_ATTRIBUTE_VALUE:
      return ("Invalid attribute value");
    case E_ATTRIBUTE_VALUE_LEN:
      return ("Invaild attribte value length");    
    case E_APPL_CTX:
      return ("Invalid application context"); 
      
    case E_BER_ENCODING:
      return ("Invalid format for BER encoding");
      
    case E_CANCEL:
      return ("Operation cancelled");
    case E_CERT_EXTENSIONS:
      return ("Invalid certificate extensions");
    case E_CERT_OBJ:
      return ("Invalid certificate object");
    case E_CERT_FIELDS:
      return ("Invalid certificate fields");
    case E_CERT_REQUEST_ENCODING:
      return ("Invalid certificate request encoding");
    case E_CERT_REQUEST_FIELDS:
      return ("Invalid certificate request fields");
    case E_CERT_REQUEST_OBJ:
      return ("Invalid certificate request object");
    case E_CERT_SERIAL:
      return ("Invalid certificate serial number");
    case E_VALIDITY:
      return ("Invalid certificate validity or CRL date");
    case E_CERT_VERSION:
      return ("Invalid certificate version");
    case E_COMPUTE_DIGEST:
      return ("Fail to compute the message digest");
      
    case E_CRL_OBJ:
      return ("Invalid CRL object");
    case E_CRL_ENTRIES_OBJ:
      return ("Invalid CRL entries object");
    case E_CRL_ENTRY_EXTENSIONS:
      return ("Invalid crl entry extensions");
    case E_CRL_EXTENSIONS:
      return ("Invalid crl extensions");
    case E_CRL_FIELDS:     
      return ("Invalid CRL fields");
    case E_INNER_DER_UNKNOWN:
      return ("Unknown inner DER value");
    case E_INVALID_CRITICALITY:
      return ("Invalid criticality");
    case E_INVALID_SIGNATURE:
      return ("Invalid signature");
      
      
    case E_DATA:
      return ("Generic data error"); 
    case E_DER_UNKNOWN:
      return ("DER value in unknown");
    case E_DEFAULT_STANDARD_EXTENSION:
      return ("Unregister default standard extension not allowed");

    case E_EXTENSIONS_OBJ:
      return ("Invalid extensions object"); 
    case E_EXTENSIONS_OBJ_TYPE:
      return ("Invalid extensions object type");
    case E_EXTENSION_ALREADY_EXISTS:
      return ("Extension already exists");
    case E_EXTENSION_TYPE_NOT_ALLOWED:
      return ("Extension type not allowed");
      
      
    case E_INDEX:
      return ("Index is out of range");
    case E_INPUT_DATA:
      return ("Invalid input data");
    case E_INPUT_LEN:
      return ("Invalid length for input data");
    case E_ISSUER_NAME:
      return ("Invalid issuer name");
    case E_INVALID_HANDLER:
      return ("Invalid extension handler");
    case E_INVALID_PARAMETER:
      return ("Invalid input parameter");
      
    case E_KEY_TYPE_NOT_SUPPORTED:
      return ("Key type is not supported"); 

    case E_LIST_OBJ:
      return ("Invalid list object");

    case E_MULTIPLE_VALUES_NOT_ALLOWED:
      return ("Multiple extension values not allowed");
      
    case E_NAME_OBJ:
      return ("Invalid name object"); 
    case E_NAME_ENCODING:
      return ("Invalid name encoding");
    case E_NOT_FOUND:
      return ("Certificate, private key or CRL was not found");
    case E_NOT_SUPPORTED:
      return ("Unsupported operation was requested"); 
      
    case E_OUTPUT_LEN:
      return ("Invalid length for output data");
    case E_OVER_32K:
      return ("Data block exceeds 32,767 bytes");
    case E_OVERRIDE_CRITICAL_NOT_ALLOWED:
      return ("Overide extension criticality not allowed");
    case E_OVERRIDE_HANDLER_NOT_ALLOWED:
      return ("Overide extension handler not allowed");
      
      
    case E_PRIVATE_KEY:
      return ("Invalid private key format");
    case E_PUBLIC_KEY:
      return ("Invalid public key format");
      
    case E_SIGNATURE_ALG_NOT_SUPPORTED:
      return ("Unsupported certificate or CRL signature algorithm");
    case E_SIGNATURE_ALG_UNKNOWN:
      return ("Unknown certificate or CRL signature algorithm");
    case E_SIGN_MACRO_OBJECT:
      return ("Invalid sign macro");
    case E_SIGN_VALUE_UNKNOWN:
      return ("Unknown signed value");
    case E_SUBJECT_NAME:
      return ("Invalid subject name");
 
    case E_UNKNOWN_CRITICAL_EXTENSION:  
      return ("Unrecognized critical extension is found");
    
    case E_VALUE_INDEX:
      return ("Invalid value index");
    case E_CERT_REQUEST_VERSION:
      return ("Invalid certificate request version"); 
    case E_CRL_VERSION:
      return ("Invalid CRL version"); 
    default:
      return ((char *)NULL_PTR);
  }
}

/* Return the error string for the type, or (char *)NULL_PTR if the type
     is not recognized.
 */
static char *BSAFE_ErrorString (type)
int type;
{
  switch (type) {
  case BE_ALGORITHM_ALREADY_SET:
    return ("Algorithm object has already been set with algorithm info");
  case BE_ALGORITHM_INFO:
    return ("Invalid algorithm info format");
  case BE_ALGORITHM_NOT_INITIALIZED:
    return ("Algorithm object has not been initialized");
  case BE_ALGORITHM_NOT_SET:
    return ("Algorithm object has not been set with algorithm info");
  case BE_ALGORITHM_OBJ:
    return ("Invalid algorithm object");
  case BE_ALG_OPERATION_UNKNOWN:
    return ("Unknown operation for an algorithm or algorithm info type");
  case BE_ALLOC:
    return ("Insufficient memory");
  case BE_CANCEL:
    return ("Operation was cancelled by the surrender function");
  case BE_DATA:
    return ("Generic data error");
  case BE_EXPONENT_EVEN:
    return ("Invalid even value for public exponent in keypair generation");
  case BE_EXPONENT_LEN:
    return
      ("Invalid exponent length for public exponent in keypair generation");
  case BE_HARDWARE:
    return ("Cryptographic hardware error");
  case BE_INPUT_DATA:
    return ("Invalid format for input data");
  case BE_INPUT_LEN:
    return ("Invalid length for input data");
  case BE_KEY_ALREADY_SET:
    return ("Key object has already been set with key info");
  case BE_KEY_INFO:
    return ("Invalid key info format");
  case BE_KEY_NOT_SET:
    return ("Key object has not been set with key info");
  case BE_KEY_OBJ:
    return ("Invalid key object");
  case BE_KEY_OPERATION_UNKNOWN:
    return ("Unknown operation for a key info type");
  case BE_MEMORY_OBJ:
    return ("Invalid internal memory object");
  case BE_MODULUS_LEN:
    return ("Invalid modulus length in public or private key");
  case BE_NOT_SUPPORTED:
    return ("Unsupported operation requested");
  case BE_OUTPUT_LEN:
    return ("Output data is larger than supplied buffer");
  case BE_OVER_32K:
    return ("Data block exceeds 32,767 bytes");
  case BE_RANDOM_NOT_INITIALIZED:
    return ("Random algorithm has not been initialized");
  case BE_RANDOM_OBJ:
    return ("Invalid algorithm object for the random algorithm");
  case BE_SIGNATURE:
    return ("Invalid signature");
  case BE_WRONG_ALGORITHM_INFO:
    return ("Wrong type of algorithm info");
  case BE_WRONG_KEY_INFO:
    return ("Wrong type of key info");
  default:
    return ((char *)NULL_PTR);
  }
}

char *GetErrorMessage (status)
int status;
{
  char *errorString;

  if (status >= 0x0200 && status <= 0x02ff)
    errorString = BSAFE_ErrorString (status); 
  else if (status >=  0x0700 && status <= 0x7ff)
    errorString = BCERT_ErrorString (status);
  else
    errorString = Demo_ErrorString (status);
  return (errorString);
  
    
}

char *GetSignatureAlgorithmName (algorithmNumber)
unsigned int algorithmNumber;
{
  switch (algorithmNumber) {
    case SA_MD2_WITH_RSA_ENCRYPTION:
      return ("MD2 WITH RSA ENCRYPTION");
    case SA_MD5_WITH_RSA_ENCRYPTION:
      return ("MD5 WITH RSA ENCRYPTION");
    default:
      return ("UNSUPPORT SIGNATURE ALGORITHM");
  }
}  


char *GetAtttributeType (type)
ITEM *type;
{
  if (AT_COUNTRY_LEN == type->len && !T_memcmp
    ((POINTER)type->data, (POINTER)AT_COUNTRY, AT_COUNTRY_LEN))
    return ("C");
    
  if (AT_STATE_LEN == type->len && !T_memcmp
    ((POINTER)type->data, (POINTER)AT_STATE, AT_STATE_LEN))
    return ("ST");

  if (AT_LOCALITY_LEN == type->len && !T_memcmp
    ((POINTER)type->data, (POINTER)AT_LOCALITY, AT_LOCALITY_LEN))
    return ("L");
  
  if (AT_ORGANIZATION_LEN == type->len && !T_memcmp
    ((POINTER)type->data, (POINTER)AT_ORGANIZATION, AT_ORGANIZATION_LEN))
    return ("O");

  if (AT_ORGANIZATION_LEN == type->len && !T_memcmp
    ((POINTER)type->data, (POINTER)AT_ORGANIZATION, AT_ORGANIZATION_LEN))
    return ("O");

  if (AT_ORG_UNIT_LEN == type->len && !T_memcmp
    ((POINTER)type->data, (POINTER)AT_ORG_UNIT, AT_ORG_UNIT_LEN))
    return ("OU");

  if (AT_COMMON_NAME_LEN == type->len && !T_memcmp
    ((POINTER)type->data, (POINTER)AT_COMMON_NAME, AT_COMMON_NAME_LEN))
    return ("CN");

  if (AT_TITLE_LEN == type->len && !T_memcmp
    ((POINTER)type->data, (POINTER)AT_TITLE, AT_TITLE_LEN))
    return ("T");

  return ((char *)NULL_PTR);
}

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