RSA BSAFE Crypto-C

Cryptographic Components for C

Search

rsamultp.c

/* $Id: rsamultp.c,v 1.5 2004/12/03 02:08:38 sparki Exp $ */
/*
 * Copyright (C) 1998-2004 RSA Security Inc.
 *
 * This file shall only be used to demonstrate how to interface to an
 * RSA Security Inc. licensed development product.
 *
 * You have a royalty-free right to use, reproduce and distribute this
 * demonstration file, provided that you agree that RSA Security Inc.
 * has no warranty, implied or otherwise, or liability for this
 * demonstration file (including any modified version).  This software
 * is provided "as is" without warranties or representations of any
 * kind. RSA Security disclaims all conditions and warranties, statutory
 * and otherwise, both express and implied, with respect to the software,
 * its quality and performance, including but not limited to, all
 * implied warranties of merchantability, fitness for a particular
 * purpose, title and noninfringement of third party rights. Without
 * limiting the foregoing, RSA Security does not warrant that the
 * software is error-free or that errors in the product will be
 * corrected. You agree that RSA Security shall not be liable for any
 * direct, indirect, incidental, special, consequential, punitive or
 * other damages whatsoever resulting from your use of this software
 * or any modified version.
 *
 *
 */

/*  This program will generate a MultiPrime RSA keypair and print out
 *  some information about the generated keys.  The program will also
 *  demonstrate extracting data from a MultiPrime vs. a standard RSA
 *  private key.
 *
 *  Warning: in a real application more care must be taken with
 *  the private keys since they contain highly sensitive information.
 */

#include "bsafe.h"
#include "demoutil.h"  /* in samples/common/include */
#include "bsfutil.h"   /* in samples/common/include */
#include "surrctx.h"   /* in samples/common/include */
#include "rsautil.h"   /* in samples/pkalg/rsa */

#define NUM_PRIMES 3
#define RSA_MODULUS_BITS 1024
#define BLOCK_SIZE ((RSA_MODULUS_BITS + 7) / 8)

/* Print out detailed information about the RSA private key.  Note that in
 * this program, we call this function with both a MultiPrime and a standard
 * RSA private key.  KI_PKCS_RSAMultiPrimePrivate is used to read information
 * about both types of keys!
 */
static int PrintRSAPrivateKeyDetails (B_KEY_OBJ privateKey);

#ifdef CRYPTOC_APP
#define MAIN rsamultpMain
#else
#define MAIN main
#endif

int MAIN(int argc, char *argv[])
{
  int status;
  B_ALGORITHM_OBJ randomAlgorithm = NULL;
  B_KEY_OBJ publicKey = NULL, privateKey = NULL;
  B_KEY_OBJ mpPublicKey = NULL, mpPrivateKey = NULL;

  ITEM *keyBER = NULL;

  do {
    /* The RSA_* demo code utilities are described in
       common/include/demoutil.h.  This procedure simply checks the
       command-line arguments for input or output options. */
    if ((status = RSA_SetOptions (argc, argv)) != 0)
      break;

    RSA_PrintMessage ("RSA MultiPrime Key Info\n");
    RSA_PrintMessage ("=======================\n");

    if ((status = RSA_CreateRandomAlgorithmObject (&randomAlgorithm)) != 0)
      break;

    RSA_PrintMessage ("Generating RSA MultiPrime keypair...\n");
    /* The following function is in samples/pkalg/rsa/rsautil.c */
    if ((status = RSA_CreateMultiPrimeRSAKeypair
                    (&mpPublicKey, &mpPrivateKey, RSA_MODULUS_BITS,
                     NUM_PRIMES, randomAlgorithm)) != 0)
      break;

    /* Obtain BER-encoded keypairs and optionally save the binary keys to a
       file for further inspection.  Note that B_GetKeyInfo gives us pointers
       to memory that belongs to the Crypto-C library.  Subsequent calls to
       Crypto-C could cause the data in those buffers to change, so the
       calling application must make a copy if this data is expected to
       persist after another Crypto-C call is made.  In this example, we do
       everything we need to with the data in these buffers before making a
       subsequent Crypto-C call, so we do not make copies here.  */
    if ((status = B_GetKeyInfo ((POINTER *)&keyBER, mpPublicKey,
                                KI_RSAPublicBER)) != 0)
      break;

    RSA_PrintBuf ("\nRSA MultiPrime Public Key", keyBER->data, keyBER->len);
    RSA_PrintMessage ("Enter name of file to store MultiPrime RSA Public Key");
    status = RSA_WriteDataToFile (keyBER->data, keyBER->len,
                                  "\n(blank not to save)");
    if ((status != 0) && (status != RSA_DEMO_E_CANCEL))
      break;

    if ((status = B_GetKeyInfo ((POINTER *)&keyBER, mpPrivateKey,
                                KI_PKCS_RSAPrivateBER)) != 0)
      break;

    RSA_PrintBuf ("RSA MultiPrime Private Key", keyBER->data, keyBER->len);
    RSA_PrintMessage ("Enter name of file to store MultiPrime RSA Private Key");
    status = RSA_WriteDataToFile (keyBER->data, keyBER->len,
                                  "\n(blank not to save)");
    if ((status != 0) && (status != RSA_DEMO_E_CANCEL))
      break;

    /* Print the private key fields which are extracted using
       KI_PKCS_RSAMultiPrimePrivate */
    if ((status = PrintRSAPrivateKeyDetails (mpPrivateKey)) != 0)
      break;

    RSA_PrintMessage ("Generating another standard RSA keypair...\n");
    if ((status = RSA_CreateRSAKeypair 
                    (&publicKey, &privateKey,
                     RSA_MODULUS_BITS, randomAlgorithm)) != 0)
      break;

    /* Obtain BER-encoded keypairs and optionally save the binary keys to a
       file for further inspection. */
    if ((status = B_GetKeyInfo ((POINTER *)&keyBER, publicKey,
                                KI_RSAPublicBER)) != 0)
      break;

    RSA_PrintBuf ("\nRSA Public Key", keyBER->data, keyBER->len);
    RSA_PrintMessage ("Enter name of file to store RSA Public Key");
    status = RSA_WriteDataToFile (keyBER->data, keyBER->len,
                                  "\n(blank not to save)");
    if ((status != 0) && (status != RSA_DEMO_E_CANCEL))
      break;

    if ((status = B_GetKeyInfo ((POINTER *)&keyBER, privateKey,
                                KI_PKCS_RSAPrivateBER)) != 0)
      break;

    RSA_PrintBuf ("RSA Private Key", keyBER->data, keyBER->len);
    RSA_PrintMessage ("Enter name of file to store RSA Private Key");
    status = RSA_WriteDataToFile (keyBER->data, keyBER->len,
                                  "\n(blank not to save)");
    if ((status != 0) && (status != RSA_DEMO_E_CANCEL))
      break;

    /* Print the private key fields which are also extracted using
       KI_PKCS_RSAMultiPrimePrivate.  After all, a "standard" RSA key pair
       generated using KI_RSAKeyGen has two primes which make up the
       modulus */
    if ((status = PrintRSAPrivateKeyDetails (privateKey)) != 0)
      break;
  } while (0);

  if (status != 0)
    RSA_PrintError ("rsamultp", status);
  else
    RSA_PrintMessage ("Testcase successful!\n");

  /*  Destroy the key objects  */
  B_DestroyKeyObject (&mpPrivateKey);
  B_DestroyKeyObject (&mpPublicKey);
  B_DestroyKeyObject (&privateKey);
  B_DestroyKeyObject (&publicKey);

  return (status);
} /*  end main  */

/* Print out detailed information about the RSA private key.  Note that in
 * this program, we call this function with both a MultiPrime and a standard
 * RSA private key.  KI_PKCS_RSAMultiPrimePrivate is used to read information
 * about both types of keys!
 */
static int PrintRSAPrivateKeyDetails(B_KEY_OBJ privateKey)
{
  int status;
  unsigned int i;

  A_PKCS_RSA_MULTI_PRIME_PRIVATE_KEY *privateKeyInfo = NULL;

  status = B_GetKeyInfo ((POINTER *)&privateKeyInfo, privateKey,
                         KI_PKCS_RSAMultiPrimePrivate);
  if (status != 0)
    return status;

  RSA_PrintMessage ("Private key details...\n");
  RSA_PrintBuf ("Modulus", privateKeyInfo->modulus.data,
                privateKeyInfo->modulus.len);
  RSA_PrintBuf ("Public Exponent", privateKeyInfo->publicExponent.data,
                privateKeyInfo->publicExponent.len);
  RSA_PrintBuf ("Private Exponent", privateKeyInfo->privateExponent.data,
                privateKeyInfo->privateExponent.len);

  RSA_PrintMessage ("Number of primes = %d\n", privateKeyInfo->numberOfPrimes);

  for (i = 0; i < privateKeyInfo->numberOfPrimes; i++) {
    ITEM prime = privateKeyInfo->primes[i];

    RSA_PrintMessage ("Prime #%d (%d bytes):\n", i + 1, prime.len);
    RSA_PrintBuf (NULL, prime.data, prime.len);
  }

  for (i = 0; i < privateKeyInfo->numberOfPrimes; i++) {
    ITEM primeExp = privateKeyInfo->primeExponents[i];

    RSA_PrintMessage ("Prime Exponent #%d (%d bytes):\n", i + 1, primeExp.len);
    RSA_PrintBuf (NULL, primeExp.data, primeExp.len);
  }

  for (i = 0; i < (privateKeyInfo->numberOfPrimes - 1); i++) {
    ITEM crtCoeff = privateKeyInfo->coefficients[i];

    RSA_PrintMessage ("Coefficient #%d (%d bytes):\n", i + 1, crtCoeff.len);
    RSA_PrintBuf (NULL, crtCoeff.data, crtCoeff.len);
  }

  return status;
} /* end PrintRSAPrivateKeyDetails */

Copyright (c) 1999-2005 RSA Security Inc. All rights reserved. 068-001001-6210-001-000 - 6.2.1