| RSA BSAFE Crypto-C |
Cryptographic Components for C |
| Search |
/* $Id: b64.c,v 1.6 2004/12/03 02:08:34 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 convert a file containing * base-64-encoded (ascii-encoded) data to binary. */ #include "bsafe.h" #include "demoutil.h" /* in samples/common/include */ /* Prompt the user for a file containing binary data. Base-64 encode the * binary data, display the ascii-encoded data, and save it to a file. */ int RSA_GetBinaryFileToAscii (); /* Prompt the user for a file containing ascii-encoded data. Base-64 decode * the ascii data and save the resulting binary to a file. */ int RSA_GetAsciiFileToBinary (); /* Base-64 decode ascii data. The buffer supplied should be the same size as * the input buffer. This is just for simplicity; the output data will * be smaller than the input data. */ static int AsciiDecode (ITEM *asciiEncoding, unsigned char *binary, unsigned int binaryMaxLen, unsigned int *binaryLen); /* Base-64 encode binary data. For simplicity, supply a buffer twice the * size of the binary input to hold the ascii-encoded data. */ static int AsciiEncode (ITEM *binaryData, unsigned char *asciiEncoding, unsigned int asciiEncodingMaxLen, unsigned int *asciiEncodingLen); /* Given data produced by B_EncodeUpdate()/B_EncodeFinal, add the necessary * carriage returns so that there are charsPerLine characters per line. * as Crypto-C does not do this automatically. The string pointer * will point to a null-terminated string. * * The calling function should free the string buffer. */ static int BsafeAsciiToFormattedString (ITEM *ascii, unsigned int charsPerLine, char **string); #ifdef CRYPTOC_APP #define MAIN b64Main #else #define MAIN main #endif int MAIN(int argc, char *argv[]) { int status = 0; char command[RSA_DEMO_MAX_LINE_LEN]; status = RSA_SetOptions (argc, argv); if (status != 0) goto CLEANUP; RSA_PrintMessage ("Base-64 Encoding/Decoding Demo\n"); RSA_PrintMessage ("==============================\n"); for (;;) { RSA_PrintMessage (" A - Convert a file from binary to ascii\n"); RSA_PrintMessage (" B - Convert a file from ascii to binary\n"); status = RSA_GetCommand (command, sizeof (command), "Enter choice (blank to quit)"); if (status != 0) goto CLEANUP; switch (command[0]) { case 'a': case 'A': status = RSA_GetBinaryFileToAscii (); break; case 'b': case 'B': status = RSA_GetAsciiFileToBinary (); break; case '\0': case 'q': case 'Q': goto CLEANUP; default: RSA_PrintMessage ("Unrecognized Option: %c\n", command[0]); status = RSA_DEMO_E_INVALID_PARAMETER; } if (status != 0) { RSA_PrintMessage ("Operation not completed.\n"); goto CLEANUP; } else RSA_PrintMessage ("Operation successful!\n"); } CLEANUP: if (status != 0) RSA_PrintError ("b64.c", status); return status; } /* end main */ int RSA_GetBinaryFileToAscii() { int status = 0; char *string = NULL; ITEM binaryData = {NULL, 0}, asciiData = {NULL, 0}; status = RSA_GetFileToAllocBuffer (&binaryData.data, &binaryData.len, "Enter name of file containing binary data"); if (status != 0) goto CLEANUP; /* Ensure that there are at least 4 bytes for the ascii data, in case there is only one binary byte to encode */ asciiData.len = (binaryData.len * 2) + 4; asciiData.data = T_malloc (asciiData.len); if (asciiData.data == NULL) { status = RSA_DEMO_E_ALLOC; goto CLEANUP; } status = AsciiEncode (&binaryData, asciiData.data, asciiData.len, &asciiData.len); if (status != 0) goto CLEANUP; status = BsafeAsciiToFormattedString (&asciiData, 76, &string); if (status != 0) goto CLEANUP; RSA_PrintMessage ("Binary data length = %u bytes\n", binaryData.len); RSA_PrintMessage ("Ascii data buffer size = %u bytes\n", asciiData.len); RSA_PrintMessage ("\nAscii-encoded data:\n%s\n", string); status = RSA_WriteDataToFile ((unsigned char *)string, T_strlen (string), "Enter name of file to store ascii data"); CLEANUP: if (status != 0) RSA_PrintError ("RSA_GetBinaryFileToAscii", status); T_free (binaryData.data); T_free (asciiData.data); T_free ((unsigned char *)string); return status; } /* end RSA_GetBinaryFileToAscii */ int RSA_GetAsciiFileToBinary() { int status = 0; ITEM asciiData = {NULL, 0}, binaryData = {NULL, 0}; status = RSA_GetFileToAllocBuffer (&asciiData.data, &asciiData.len, "Enter name of file containing ascii data"); if (status != 0) goto CLEANUP; binaryData.len = asciiData.len; binaryData.data = T_malloc (binaryData.len); if (binaryData.data == NULL) { status = RSA_DEMO_E_ALLOC; goto CLEANUP; } status = AsciiDecode (&asciiData, binaryData.data, binaryData.len, &binaryData.len); if (status != 0) goto CLEANUP; RSA_PrintMessage ("Ascii data buffer size = %u bytes\n", asciiData.len); RSA_PrintMessage ("Binary data length = %u bytes\n", binaryData.len); status = RSA_WriteDataToFile (binaryData.data, binaryData.len, "Enter name of file to store binary data"); CLEANUP: if (status != 0) RSA_PrintError ("RSA_GetAsciiFileToBinary", status); return status; } /* end RSA_GetAsciiFileToBinary */ static int AsciiDecode(ITEM *asciiEncoding, unsigned char *binary, unsigned int binaryMaxLen, unsigned int *binaryLen) { int status = 0; unsigned int outputLenUpdate = 0, outputLenFinal = 0; B_ALGORITHM_OBJ decoder = NULL; status = B_CreateAlgorithmObject (&decoder); if (status != 0) goto CLEANUP; status = B_SetAlgorithmInfo (decoder, AI_RFC1113Recode, NULL); if (status != 0) goto CLEANUP; status = B_DecodeInit (decoder); if (status != 0) goto CLEANUP; status = B_DecodeUpdate (decoder, binary, &outputLenUpdate, binaryMaxLen, asciiEncoding->data, asciiEncoding->len); if (status != 0) goto CLEANUP; status = B_DecodeFinal (decoder, binary+outputLenUpdate, &outputLenFinal, binaryMaxLen-outputLenUpdate); if (status != 0) goto CLEANUP; *binaryLen = outputLenUpdate + outputLenFinal; CLEANUP: if (status != 0) { *binaryLen = 0; RSA_PrintError ("AsciiDecode", status); } B_DestroyAlgorithmObject (&decoder); return status; } /* end AsciiDecode */ static int AsciiEncode(ITEM *binaryData, unsigned char *asciiEncoding, unsigned int asciiEncodingMaxLen, unsigned int *asciiEncodingLen) { int status = 0; unsigned int outputLenUpdate = 0, outputLenFinal = 0; B_ALGORITHM_OBJ encoder = NULL; status = B_CreateAlgorithmObject (&encoder); if (status != 0) goto CLEANUP; status = B_SetAlgorithmInfo (encoder, AI_RFC1113Recode, NULL); if (status != 0) goto CLEANUP; status = B_EncodeInit (encoder); if (status != 0) goto CLEANUP; status = B_EncodeUpdate (encoder, asciiEncoding, &outputLenUpdate, asciiEncodingMaxLen, binaryData->data, binaryData->len); if (status != 0) goto CLEANUP; status = B_EncodeFinal (encoder, asciiEncoding+outputLenUpdate, &outputLenFinal, asciiEncodingMaxLen-outputLenUpdate); if (status != 0) goto CLEANUP; *asciiEncodingLen = outputLenUpdate + outputLenFinal; CLEANUP: if (status != 0) { *asciiEncodingLen = 0; RSA_PrintError ("AsciiEncode", status); } B_DestroyAlgorithmObject (&encoder); return status; } /* end AsciiEncode */ static int BsafeAsciiToFormattedString(ITEM *ascii, unsigned int charsPerLine, char **string) { int status = 0, stringBytes = 0, stringIndex = 0; unsigned int asciiIndex = 0; stringBytes = (ascii->len + (ascii->len + charsPerLine - 1) / charsPerLine) + 1; *string = (char *)T_malloc (stringBytes); if (*string == NULL) { status = BE_ALLOC; goto CLEANUP; } T_memset ((unsigned char *)*string, 0, stringBytes); for (asciiIndex = 0; asciiIndex < ascii->len; asciiIndex++) { (*string)[stringIndex++] = ascii->data[asciiIndex]; if ((asciiIndex % charsPerLine == charsPerLine - 1) || (asciiIndex + 1 == ascii->len)) (*string)[stringIndex++] = '\n'; } CLEANUP: if (status != 0) { T_free ((unsigned char *)*string); *string = NULL; RSA_PrintError ("BsafeAsciiToFormattedString", status); } return status; } /* end BsafeAsciiToFormattedString */