| RSA BSAFE Crypto-C |
Cryptographic Components for C |
| Search |
/* $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 */