#include #include #include #define MY_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) //-------------------------------------------------------------------- // The local function MyHandleError is declared here and // defined after main. void MyHandleError( char *s); //-------------------------------------------------------------------- // The local function ReadFileBlob is declared here and // defined after main. BYTE *ReadFileBlob(LPCSTR filename, DWORD *cbBlob); //-------------------------------------------------------------------- //-------------------------------------------------------------------- // The local function FileBinout is declared here and // defined after main. void FileBinout(LPCSTR filename, DWORD bCount, BYTE *binarydata); //-------------------------------------------------------------------- void main() { BYTE *pbBlob; DWORD cbBlob; PCHAR szSource; BYTE *pbData; //decoded data BYTE *pbData1; //decoded data DWORD cbData; CERT_PUBLIC_KEY_INFO pkinfo; LPCSTR subjectpublickeyinfo = "subjectpublickeyinfo" ; LPCSTR rsapublickey = "rsapublickey" ; BOOL isRSAPublicKey = FALSE; BOOL isPUBLICKEYBLOB = FALSE; if(!(szSource=(char *)malloc(100))) MyHandleError("Memory allocation failed."); printf("Enter CryptoAPI PUBLICKEYBLOB or RSAPublicKey file: "); fgets(szSource, 100, stdin); if(szSource[strlen(szSource)-1] == '\n') szSource[strlen(szSource)-1] = '\0'; //--- Read key file into byte buffer --------- if( (pbBlob = ReadFileBlob(szSource, &cbBlob)) == NULL ) { MyHandleError("Couldn't read file. "); } else { printf("\nRead '%s' file into buffer: %d bytes.\n", szSource, cbBlob); } //----- Sanity Check .. see if this is an RSAPublicKey or SubjectPublicKeyInfo blob cbData=0; if (CryptDecodeObject(MY_TYPE, X509_PUBLIC_KEY_INFO, pbBlob, cbBlob, 0, NULL, &cbData)) MyHandleError("File is a valid SubjectPublicKeyInfo blob\n"); //we're done if (CryptDecodeObject(MY_TYPE,RSA_CSP_PUBLICKEYBLOB, pbBlob, cbBlob, 0, NULL, &cbData)) { printf("\nFile '%s' is a valid RSAPublicKey blob\n", szSource); isRSAPublicKey = TRUE; } //--- Try to Encode to RSA_PUBLICKey if blob is a PUBLICKEYBLOB --------- cbData=0; if (CryptEncodeObject( MY_TYPE, RSA_CSP_PUBLICKEYBLOB, pbBlob, NULL, &cbData)) { //printf("\nBuffer size for RSAPublicKey: %d\n", cbData); if(!(pbData = (BYTE *)malloc(cbData))) MyHandleError("Memory allocation failed."); if (CryptEncodeObject( MY_TYPE, RSA_CSP_PUBLICKEYBLOB, pbBlob, pbData, &cbData)) { isPUBLICKEYBLOB = TRUE; printf("\nGot RSAPublicKey encoded data: %d bytes\n", cbData); FileBinout(rsapublickey, cbData, pbData) ; } else MyHandleError("Couldn't encode to RSAPublicKey.\n"); } else { printf("File '%s' is not a PUBLICKEYBLOB.\n", szSource); pbData = pbBlob; //maybe file blob is already a RSAPublicKey cbData = cbBlob; } if(!isRSAPublicKey && !isPUBLICKEYBLOB) MyHandleError("File is not a recognized keyblob format") ; //----- We have a valid RSAPublicKey; try to encode to SubjectPublicKeyInfo -------------- // First build the CERT_PUBLIC_KEY_INFO struct --------- pkinfo.Algorithm.pszObjId = szOID_RSA_RSA; pkinfo.Algorithm.Parameters.cbData = 2; pkinfo.Algorithm.Parameters.pbData = (BYTE *) "\005"; pkinfo.PublicKey.cbData = cbData; pkinfo.PublicKey.pbData = pbData; pkinfo.PublicKey.cUnusedBits = 0; cbData=0; if (CryptEncodeObject( MY_TYPE, X509_PUBLIC_KEY_INFO, &pkinfo, 0, &cbData)) { // printf("\nBuffer size for SubjectPublicKeyInfo: %d\n", cbData); } else { MyHandleError("Couldn't encode to SubjectPublicKeyInfo size.\n"); } //---------------------------------------------------- // Allocate memory for the required buffer. if(!(pbData1 = (BYTE *)malloc(cbData))) MyHandleError("Memory allocation failed."); //---------------------------------------------------- if (CryptEncodeObject( MY_TYPE, X509_PUBLIC_KEY_INFO, &pkinfo, pbData1, &cbData)) { printf("\nGot SubjectPublicKeyInfo encoded data: %d bytes\n", cbData); FileBinout(subjectpublickeyinfo, cbData, pbData1); } else { MyHandleError("Couldn't encode to SubjectPublicKeyInfo.\n"); } //-- clean up ---- if(szSource) free(szSource); if(pbBlob) free(pbBlob); if(pbData) free(pbData); if(pbData1) free(pbData1); } // end of main. BYTE *ReadFileBlob(LPCSTR fname, DWORD *cbBlob) { FILE *hInputFile; BYTE *pbBlob; DWORD dwFSize; long save; if( !(hInputFile= fopen(fname,"rb"))) { MyHandleError("Input file was not opened.\n"); } save = ftell(hInputFile); fseek(hInputFile, 0, SEEK_END); dwFSize = ftell(hInputFile); fseek(hInputFile, save, SEEK_SET); if(!(pbBlob = (BYTE *) malloc(dwFSize))) { MyHandleError("Memory allocation failed."); } *cbBlob = fread( pbBlob, 1, dwFSize, hInputFile); //printf("Read %d bytes\n", *cbBlob) ; if(ferror(hInputFile)) { MyHandleError("The bytes of the BLOB were not read.\n"); } fclose(hInputFile); return pbBlob; } // End of ReadBlob void MyHandleError(char *s) { printf("%s\n",s); exit(1); } void FileBinout(LPCSTR binfile, DWORD bytes, BYTE *bindata) { FILE *stream; int numwritten; errno_t err; /* Open for binary read-write */ if( (err = fopen_s( &stream, binfile, "w" )) !=0 ) printf( "File %s was not opened\n", binfile ); else{ numwritten = fwrite( bindata, sizeof( char ), bytes, stream ); printf( "Wrote %d bytes to file '%s'\n", numwritten, binfile ); } /* Close stream */ fclose( stream ); }