| RSA BSAFE Cert-C |
Certificate Components for C |
| Crypto-C 6.2.1 Developer's Guide | ||
| Search |
/* $Id: b64.c,v 1.6 2005/01/28 02:30:21 alockwoo Exp $ */ /* b64.c ** Copyright (c) 1999-2003, RSA Security Inc. ** ** This file is used to demonstrate how to interface to an RSA Security ** licensed development product. You have a royalty-free right to use, ** modify, reproduce and distribute this demonstration file (including ** any modified version), provided that you agree that RSA Security has ** no warranty, implied or otherwise, or liability for this demonstration ** file or any modified version. ** ** This program will convert a file containing binary data to ascii, or ** convert a file containing base-64-encoded (ascii-encoded) data to binary. ** This really should be a Crypto-C sample, but is provided for convenience. */ #include "demoutil.h" #ifdef _MSC_VER # pragma warning (disable: 171) /* invalid type conversion (often of very similar ptrs) */ #endif /* 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. */ static int RSA_GetBinaryFileToAscii (void); /* Prompt the user for a file containing ascii-encoded data. Base-64 decode * the ascii data and save the resulting binary to a file. */ static int RSA_GetAsciiFileToBinary (void); /* 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. * Crypto-C (unlike Crypto-J) does not do this for you. 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); /* 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. This * function uses C_EncodeBase64. */ static int CertC_GetBinaryFileToAscii (void); /* Prompt the user for a file containing ascii-encoded data. Base-64 decode * the ascii data and save the resulting binary to a file. This function * uses C_DecodeBase64. */ static int CertC_GetAsciiFileToBinary (void); int main (int argc, char *argv[]) { int status = 0; char command[RSA_DEMO_MAX_LINE_LEN]; status = RSA_SetOptions (NULL, 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"); RSA_PrintMessage (" C - Use C_EncodeBase64 to go from binary to ascii\n"); RSA_PrintMessage (" D - Use C_DecodeBase64 to go 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 'c': case 'C': status = CertC_GetBinaryFileToAscii (); break; case 'd': case 'D': status = CertC_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 */ /* See function declaration at the top for a description */ 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 someone wants to encode one binary byte... */ 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, 64, &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 */ /* See function declaration at the top for a description */ 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); T_free (binaryData.data); T_free (asciiData.data); return status; } /* end RSA_GetAsciiFileToBinary */ /* See function declaration at the top for a description */ 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 */ /* See function declaration at the top for a description */ 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 */ /* See function declaration at the top for a description */ 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 */ /* See function declaration at the top for a description */ int CertC_GetBinaryFileToAscii () { int status = 0; 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; status = C_EncodeBase64 (NULL, &asciiData.len, binaryData.data, binaryData.len); if (status != 0) goto CLEANUP; asciiData.data = T_malloc (asciiData.len); if (asciiData.data == NULL) { status = RSA_DEMO_E_ALLOC; goto CLEANUP; } RSA_PrintMessage ("Binary data length = %u bytes\n", binaryData.len); RSA_PrintMessage ("Ascii data buffer size = %u bytes\n", asciiData.len); status = C_EncodeBase64 (asciiData.data, &asciiData.len, binaryData.data, binaryData.len); if (status != 0) goto CLEANUP; status = RSA_WriteDataToFile (asciiData.data, asciiData.len, "Enter name of file to store ascii data"); CLEANUP: if (status != 0) RSA_PrintError ("CertC_GetBinaryFileToAscii", status); T_free (binaryData.data); T_free (asciiData.data); return status; } /* end CertC_GetBinaryFileToAscii */ /* See function declaration at the top for a description */ int CertC_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; status = C_DecodeBase64 (NULL, &binaryData.len, asciiData.data, asciiData.len); if (status != 0) goto CLEANUP; binaryData.data = T_malloc (binaryData.len); if (binaryData.data == NULL) { status = RSA_DEMO_E_ALLOC; goto CLEANUP; } status = C_DecodeBase64 (binaryData.data, &binaryData.len, asciiData.data, asciiData.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 ("CertC_GetAsciiFileToBinary", status); T_free (binaryData.data); T_free (asciiData.data); return status; } /* end CertC_GetAsciiFileToBinary */