| RSA BSAFE Crypto-C |
Cryptographic Components for C |
| Search |
/* $Id: rsapkcs.c,v 1.7 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 RSA keypair, encrypt with the public key, * then decrypt with the private key -- i.e. Digital Envelope. */ #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 */ B_ALGORITHM_METHOD *RSA_SAMPLE_CHOOSER[] = { &AM_RSA_ENCRYPT, &AM_RSA_DECRYPT, &AM_RSA_CRT_ENCRYPT, &AM_RSA_CRT_DECRYPT, (B_ALGORITHM_METHOD *)NULL_PTR /* This will fix a problem that the IA64 compiler finds when * * seeing a short chooser list */ #ifdef IA64_FORCE_LARGE IA64_FORCE_LARGE #endif }; #define RSA_MODULUS_BITS 512 #define BLOCK_SIZE ((RSA_MODULUS_BITS + 7) / 8) #ifdef CRYPTOC_APP #define MAIN rsapkcsMain #else #define MAIN main #endif int MAIN(int argc, char *argv[]) { B_ALGORITHM_OBJ randomAlgorithm = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ rsaDecryptor = (B_ALGORITHM_OBJ)NULL_PTR; B_KEY_OBJ publicKey = (B_KEY_OBJ)NULL_PTR; B_KEY_OBJ privateKey = (B_KEY_OBJ)NULL_PTR; A_SURRENDER_CTX generalSurrenderContext; int generalFlag; ITEM *cryptocPublicKeyBER; ITEM myPublicKeyBER = {NULL, 0}; ITEM *getPrivateKey; ITEM privateKeyBER = {NULL, 0}; /* This could be a DES or RC4 key, for example... */ unsigned char dataToEncryptWithRSA[] = { 0x4a, 0x72, 0x55, 0x36, 0xda, 0x2f, 0xb9, 0x51 }; unsigned int dataToEncryptLen = sizeof(dataToEncryptWithRSA); unsigned char encryptedData[BLOCK_SIZE]; unsigned char decryptedData[BLOCK_SIZE]; unsigned int outputLenUpdate, outputLenFinal, outputLenTotal; int status; /* See samples/common/source/surrctx.c for RSA_GeneralSurrenderFunction */ generalSurrenderContext.Surrender = RSA_GeneralSurrenderFunction; generalSurrenderContext.handle = (POINTER)&generalFlag; generalSurrenderContext.reserved = NULL_PTR; 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 PKCS #1 Algorithm\n"); RSA_PrintMessage ("=====================\n"); RSA_PrintMessage ("Maximum allowable size for data to encrypt = %d bytes\n", BLOCK_SIZE - 11); RSA_PrintBuf ("Data to Encrypt", dataToEncryptWithRSA, dataToEncryptLen); if ((status = RSA_CreateRandomAlgorithmObject (&randomAlgorithm)) != 0) break; /* The following function is in samples/pkalg/rsa/rsautil.c */ if ((status = RSA_CreateRSAKeypair (&publicKey, &privateKey, RSA_MODULUS_BITS, randomAlgorithm)) != 0) break; RSA_PrintMessage ("\n Distributing Your Public Key\n"); RSA_PrintMessage (" ============================\n"); if ((status = B_GetKeyInfo ((POINTER *)&cryptocPublicKeyBER, publicKey, KI_RSAPublicBER)) != 0) break; myPublicKeyBER.len = cryptocPublicKeyBER->len; myPublicKeyBER.data = T_malloc (myPublicKeyBER.len); if (myPublicKeyBER.data == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } T_memcpy (myPublicKeyBER.data, cryptocPublicKeyBER->data, myPublicKeyBER.len); RSA_PrintMessage ("The public key DER-encoded as X.509\n"); RSA_PrintBuf ("SubjectPublicKeyInfo type", myPublicKeyBER.data, myPublicKeyBER.len); RSA_PrintMessage (" Encrypting with the RSA Public Key\n"); RSA_PrintMessage (" ==================================\n"); /* Create an Algorithm Object */ if ((status = B_CreateAlgorithmObject (&rsaEncryptor)) != 0) break; /* Set the algorithm object to AI_PKCS_RSAPublic */ if ((status = B_SetAlgorithmInfo (rsaEncryptor, AI_PKCS_RSAPublic, NULL_PTR)) != 0) break; /* Init -- encrypt with the recipient's public key */ if ((status = B_EncryptInit (rsaEncryptor, publicKey, RSA_SAMPLE_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Update */ generalFlag = 0; if ((status = B_EncryptUpdate (rsaEncryptor, encryptedData, &outputLenUpdate, BLOCK_SIZE, dataToEncryptWithRSA, dataToEncryptLen, randomAlgorithm, &generalSurrenderContext)) != 0) break; /* Final */ generalFlag = 0; if ((status = B_EncryptFinal (rsaEncryptor, encryptedData + outputLenUpdate, &outputLenFinal, BLOCK_SIZE - outputLenUpdate, randomAlgorithm, &generalSurrenderContext)) != 0) break; outputLenTotal = outputLenUpdate + outputLenFinal; RSA_PrintBuf ("Encrypted Data", encryptedData, outputLenTotal); RSA_PrintMessage (" Decrypting with the RSA Private Key\n"); RSA_PrintMessage (" ===================================\n"); if ((status = B_GetKeyInfo ((POINTER *)&getPrivateKey, privateKey, KI_PKCS_RSAPrivateBER)) != 0) break; privateKeyBER.len = getPrivateKey->len; privateKeyBER.data = T_malloc (privateKeyBER.len); if (privateKeyBER.data == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } T_memcpy (privateKeyBER.data, getPrivateKey->data, privateKeyBER.len); RSA_PrintMessage ("The private key encoded as a PKCS #8\n"); RSA_PrintBuf ("PrivateKeyInfo type", privateKeyBER.data, privateKeyBER.len); /* Create an Algorithm Object */ if ((status = B_CreateAlgorithmObject (&rsaDecryptor)) != 0) break; /* Set the algorithm object to AI_PKCS_RSAPrivate */ if ((status = B_SetAlgorithmInfo (rsaDecryptor, AI_PKCS_RSAPrivate, NULL_PTR)) != 0) break; /* Init -- Use the private key associated with the public key used to encrypt */ if ((status = B_DecryptInit (rsaDecryptor, privateKey, RSA_SAMPLE_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Update */ generalFlag = 0; if ((status = B_DecryptUpdate (rsaDecryptor, decryptedData, &outputLenUpdate, BLOCK_SIZE, encryptedData, outputLenTotal, NULL_PTR, &generalSurrenderContext)) != 0) break; /* Final */ generalFlag = 0; if ((status = B_DecryptFinal (rsaDecryptor, decryptedData + outputLenUpdate, &outputLenFinal, BLOCK_SIZE - outputLenUpdate, NULL_PTR, &generalSurrenderContext)) != 0) break; outputLenTotal = outputLenUpdate + outputLenFinal; RSA_PrintBuf ("Decrypted Data", decryptedData, outputLenTotal); if ((outputLenTotal == dataToEncryptLen) && (T_memcmp (dataToEncryptWithRSA, decryptedData, outputLenTotal)) == 0) { RSA_PrintMessage ("Success! "); RSA_PrintMessage ("The decrypted data matches the original data.\n"); } else { RSA_PrintMessage ("The decrypted data does not match the original data."); status = RSA_DEMO_E_INFO_DOES_NOT_VERIFY; } } while (0); if (status != 0) RSA_PrintError ("rsapkcs", status); /* Destroy the key and algorithm objects */ B_DestroyAlgorithmObject (&randomAlgorithm); B_DestroyAlgorithmObject (&rsaEncryptor); B_DestroyAlgorithmObject (&rsaDecryptor); B_DestroyKeyObject (&privateKey); B_DestroyKeyObject (&publicKey); /* Free up any memory allocated */ if (myPublicKeyBER.data != NULL_PTR) T_free (myPublicKeyBER.data); if (privateKeyBER.data != NULL_PTR) T_free (privateKeyBER.data); return (status); } /* end main */