RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

asn1.c

Use the public ASN.1 APIs in Cert-C to encode and decode data

/* $Id: asn1.c,v 1.6 2004/03/02 05:18:32 gsingh Exp $ */
/* asn1.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.
**
** Demonstrate the use of the public ASN.1 APIs in Cert-C by encoding and
** decoding some arbitrary data in BER/DER format.  Another example of the
** use of the ASN.1 engine can be found in the keypair/keywrap.c demo program,
** where private keys can be encrypted as a PKCS #8 EncryptedPrivateKeyInfo.
** The ASN.1 routines can also be used to implement support for other
** certificate or CRL extensions.
**
** When compiling, define the macro RSA_REQUIRE_FILE_LOG (-D compile
** option, or equivelent) to force the program to return an error code
** if file logging cannot be initialized.  For example, if the file
** containing the log message format strings cannot be located (certc.msg
** or equivalent).
*/

#include "certc.h"
#include "filelog.h"
#include "demoutil.h"
#include "timeutil.h"

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

int main (int argc, char *argv[])
{
  int status = 0;
  unsigned char userInput[1000];
  
  CERTC_CTX ctx = NULL;
  ITEM asnNull = {NULL, 0}, utcTime = {NULL, 0}, genTime = {NULL, 0};
  ITEM utf8String = {NULL, 0}, sequence = {NULL, 0};
  
  UINT4 time = 0;
  GENERALIZED_TIME generalizedTime;
  LIST_OBJ items = NULL;

  FILE_LOG_PARAMS logParams = {NULL, NULL};
  SERVICE_HANDLER logHandler = {
    SPT_LOG, "Default File Log", S_InitializeFileLog
  };
  
  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

  RSA_PrintMessage ("ASN.1 Example\n");
  RSA_PrintMessage ("=============\n");

  /* Encoding a NULL value */
  status = C_DEREncodeNull (ctx, VT_ASN_NULL, VTC_UNIVERSAL, &asnNull.data,
                            &asnNull.len);
  if (status != 0)
    goto CLEANUP;

  RSA_PrintBuf ("\nDER-encoded NULL", asnNull.data, asnNull.len);
  
  /* Encoding different representations of time */
  status = RSA_GetInputToUint4Time (&time, "\nEnter a time to DER encode\n");
  if (status != 0)
    goto CLEANUP;

  status = C_DEREncodeUTCTime (ctx, VT_UTC_TIME, VTC_UNIVERSAL, time,
                               &utcTime.data, &utcTime.len);
  if (status != 0)
    goto CLEANUP;

  RSA_PrintBuf ("\nDER-encoded UTCTime", utcTime.data, utcTime.len);

  status = RSA_Uint4ToGeneralizedTime (&generalizedTime, &time);
  if (status != 0)
    goto CLEANUP;
  
  status = C_DEREncodeGeneralizedTime (ctx, VT_GENERALIZED_TIME, VTC_UNIVERSAL,
                                       &generalizedTime, &genTime.data,
                                       &genTime.len);
  if (status != 0)
    goto CLEANUP;

  RSA_PrintBuf ("\nDER-encoded GeneralzedTime", genTime.data, genTime.len);

  /* Encoding a user-supplied string */
  status = RSA_GetCommand ((char *)userInput, sizeof (userInput),
                           "\nEnter string to encode (blank to cancel)");
  if (status != 0)
    goto CLEANUP;

  status = C_DEREncodeString (ctx, VT_UTF8_STRING, VTC_UNIVERSAL,
                              userInput, T_strlen ((char *)userInput),
                              &utf8String.data, &utf8String.len);
  if (status != 0)
    goto CLEANUP;

  RSA_PrintBuf ("\nDER-encoded UTF-8 String", utf8String.data,
                utf8String.len);

  /* As an example, put all of these elements in a SEQUENCE... */
  status = C_CreateListObject (&items);
  if (status != 0)
    goto CLEANUP;

  status = C_AddItemToList (items, &asnNull, NULL);
  if (status != 0)
    goto CLEANUP;

  status = C_AddItemToList (items, &utcTime, NULL);
  if (status != 0)
    goto CLEANUP;

  status = C_AddItemToList (items, &genTime, NULL);
  if (status != 0)
    goto CLEANUP;

  status = C_AddItemToList (items, &utf8String, NULL);
  if (status != 0)
    goto CLEANUP;

  status = C_DEREncodeList (ctx, VT_SEQUENCE, VTC_UNIVERSAL, items,
                            &sequence.data, &sequence.len);
  if (status != 0)
    goto CLEANUP;

  RSA_PrintBuf ("\nDER-encoded sequence containing items above",
                sequence.data, sequence.len);
  
CLEANUP:
  if (status != 0)
    RSA_PrintError ("asn1.c", status);

  T_free (asnNull.data);
  T_free (utcTime.data);
  T_free (genTime.data);
  T_free (utf8String.data);
  T_free (sequence.data);
  C_DestroyListObject (&items);
  C_FinalizeCertC (&ctx);
  
  return status;
}  /* end main */

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