You are currently viewing a snapshot of www.mozilla.org taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to www.mozilla.org, please file a bug.




/*
 * Demonstration program for hashing and MACs
 */

#include <iostream.h>

#include "pk11func.h"
#include "nss.h"

static void
printDigest(unsigned char *digest, unsigned int len)
{
  int i;

  cout << "length: " << len << endl;
  for(i = 0;i < len;i++) printf("%02x ", digest[i]);
  cout << endl;
}

/*
 * main
 */
int
main(int argc, const char *argv[])
{
  int status = 0;
  PK11SlotInfo *slot = 0;
  PK11SymKey *key = 0;
  PK11Context *context = 0;
  unsigned char data[80];
  unsigned char digest[20]; /*Is there a way to tell how large the output is?*/
  unsigned int len;
  SECStatus s;

  /* Initialize NSS
   * If your application code has already initialized NSS, you can skip it
   * here.
   * This code uses the simplest of the Init functions, which does not
   * require a NSS database to exist
   */
  NSS_NoDB_Init(".");

  /* Get a slot to use for the crypto operations */
  slot = PK11_GetInternalKeySlot();
  if (!slot)
  {
    cout << "GetInternalKeySlot failed" << endl;
    status = 1;
    goto done;
  }

  /*
   *  Part 1 - Simple hashing
   */
  cout << "Part 1 -- Simple hashing" << endl;

  /* Initialize data */
  memset(data, 0xbc, sizeof data);

  /* Create a context for hashing (digesting) */
  context = PK11_CreateDigestContext(SEC_OID_MD5);
  if (!context) { cout << "CreateDigestContext failed" << endl; goto done; }

  s = PK11_DigestBegin(context);
  if (s != SECSuccess) { cout << "DigestBegin failed" << endl; goto done; }

  s = PK11_DigestOp(context, data, sizeof data);
  if (s != SECSuccess) { cout << "DigestUpdate failed" << endl; goto done; }

  s = PK11_DigestFinal(context, digest, &len, sizeof digest);
  if (s != SECSuccess) { cout << "DigestFinal failed" << endl; goto done; }

  /* Print digest */
  printDigest(digest, len);

  PK11_DestroyContext(context, PR_TRUE);
  context = 0;

  /*
   *  Part 2 - Hashing with included secret key
   */
  cout << "Part 2 -- Hashing with included secret key" << endl;

  /* Initialize data */
  memset(data, 0xbc, sizeof data);

  /* Create a Key */
  key = PK11_KeyGen(slot, CKM_GENERIC_SECRET_KEY_GEN, 0, 128, 0);
  if (!key) { cout << "Create key failed" << endl; goto done; }

  cout << (void *)key << endl;

  /* Create parameters for crypto context */
  /* NOTE: params must be provided, but may be empty */
  SECItem noParams;
  noParams.data = 0;
  noParams.len = 0;

  /* Create context using the same slot as the key */
//  context = PK11_CreateDigestContext(SEC_OID_MD5);
  context = PK11_CreateContextBySymKey(CKM_MD5, CKA_DIGEST, key, &noParams);
  if (!context) { cout << "CreateDigestContext failed" << endl; goto done; }

  s = PK11_DigestBegin(context);
  if (s != SECSuccess) { cout << "DigestBegin failed" << endl; goto done; }

  s = PK11_DigestKey(context, key);
  if (s != SECSuccess) { cout << "DigestKey failed" << endl; goto done; }

  s = PK11_DigestOp(context, data, sizeof data);
  if (s != SECSuccess) { cout << "DigestUpdate failed" << endl; goto done; }

  s = PK11_DigestFinal(context, digest, &len, sizeof digest);
  if (s != SECSuccess) { cout << "DigestFinal failed" << endl; goto done; }

  /* Print digest */
  printDigest(digest, len);

  PK11_DestroyContext(context, PR_TRUE);
  context = 0;

  /*
   *  Part 3 - MAC (with secret key)
   */
  cout << "Part 3 -- MAC (with secret key)" << endl;

  /* Initialize data */
  memset(data, 0xbc, sizeof data);

  context = PK11_CreateContextBySymKey(CKM_MD5_HMAC, CKA_SIGN, key, &noParams);
  if (!context) { cout << "CreateContextBySymKey failed" << endl; goto done; }

  s = PK11_DigestBegin(context);
  if (s != SECSuccess) { cout << "DigestBegin failed" << endl; goto done; }

  s = PK11_DigestOp(context, data, sizeof data);
  if (s != SECSuccess) { cout << "DigestOp failed" << endl; goto done; }

  s = PK11_DigestFinal(context, digest, &len, sizeof digest);
  if (s != SECSuccess) { cout << "DigestFinal failed" << endl; goto done; }

  /* Print digest */
  printDigest(digest, len);

  PK11_DestroyContext(context, PR_TRUE);
  context = 0;

done:
  if (context) PK11_DestroyContext(context, PR_TRUE);  /* freeit ?? */
  if (key) PK11_FreeSymKey(key);
  if (slot) PK11_FreeSlot(slot);

  return status;
}