CRYPT_DATA_BLOB data type to CHAR


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 1 of 3 123 LastLast
Results 1 to 15 of 38

Thread: CRYPT_DATA_BLOB data type to CHAR

  1. #1
    Join Date
    Jul 2008
    Posts
    69

    CRYPT_DATA_BLOB data type to CHAR

    Hello

    I have a variable SignedMessage of type CRYPT_DATA_BLOB. I want to convert it to Char or String. Can any body help me? I am using C++ in MS VS 8.

    regards,

    Wilayat Khan

  2. #2
    Join Date
    Dec 2003
    Posts
    3,366
    CRYPT_DATA_BLOB is not a c++ type, so you have to backtrack it and find out what it really is. Visual studio and authors of tools for it are terrible about renaming basic types into junk like

    unsigned char = byte
    handle = void *
    int = BOOL
    and many terrible things.

    In the editor, keep right clicking and going to defination until you find either a typedef or a class or struct or something that tells you what a CRYPT_DATA_BLOB is, and from there you can convert it or cast it into what you need.

  3. #3
    Join Date
    May 2007
    Posts
    843
    I agree with jonnin's opinion. Naming convention of Microsoft is pretty confused.

  4. #4
    Join Date
    Jul 2008
    Posts
    69
    Ok, i will explain it a bit more. Yes you all are true.
    CRYPT_DATA_BLOB is a structure. it consists of two elements of type


    Code:
    typedef struct _CRYPTOAPI_BLOB {
      DWORD cbData;
      BYTE* pbData;
    }CRYPT_DATA_BLOB;
    I have an object SingnedMessage of type CRYPT_DATA_BLOB. I want to send the two elements of this structure ( the whole structure, so to use it at receiver end) "cbData" and "pbData". For socket to send data, I need these two values to be in type String. I tried as below

    Code:
    CRYPT_DATA_BLOB SignedMessage;
    char BufToHoldSignedMsg[700];
    int length;
    ....
    ....
    ....
    
    lenght = (int)SignedMessage.cbData;
    BufToHoldSignedMsg = (char*)SignedMessage.pbData;
    Now I wanted to convert integer "lenght" to char and then concatenate it with BufToHoldSignedMsg, and send it to receiver, and do the reverse process to reinitialize a structure of the same kind so to use it for Signature Verification. But it gives many errors.

    Please if anybody help me in this.

    regards,
    Wilayat Khan

  5. #5
    Join Date
    Dec 2003
    Posts
    3,366
    oh, ok.

    assuming your variable is SM just to save typing:

    char sendme[1000]; //or whatever size

    memcpy(sendme, sm.cbdata, sizeof(dword));
    memcpy(&sendme[sizeof(dword)], sm.pbdata, length_of_pbdata);

    ...

    send( ... sendme, ...);

  6. #6
    Join Date
    Dec 2003
    Posts
    3,366
    Note:
    you can do it differently by knowing that a struct is already serialized if it only contains data, but I did it that above way so you could do it for *any* struct or class later on.

    Be careful with memcpy. It is unforgiving, but extremely good at what it does, sort of like pointers.

  7. #7
    Join Date
    Jul 2008
    Posts
    69

    to jonnin

    thanks for your help

    I am new with function memcpy. Have you assumed that SM is a structure and that its two elements cbData is DWORD, and pbData is BYTE* (unsigned char*)?

    if yes then, what does the sendme buffer holds? does it hold both cbData and pbData? if yes, I cant confirm it wheather it work correctly or not. As, at receiver side (for example i sent the sendme buf), i have to separate again the two elements, thats cbData and pbData, because the verifier program needs a structure of the same kind with two elements cbData and pbData initilized with the values received. so can you guide me how to do the reverse process? I mean taking out cbData (of type DWORD) and pbData (of type BYTE*) from the received buf "sendme".

    thanks in advance.

    regards,
    wilayat

  8. #8
    Join Date
    Dec 2003
    Posts
    3,366
    memcpy moves bytes around.

    I was basing my code sample off this broken struct that you posted:

    typedef struct _CRYPTOAPI_BLOB {
    DWORD cbData;
    BYTE* pbData;
    }CRYPT_DATA_BLOB;

    (should probably be this to remove archaic syntax and align brackets):

    struct CRYPT_DATA_BLOB
    {
    DWORD cbData;
    BYTE* pbData;
    };



    but this should use c++ data types for clarity:

    struct CRYPT_DATA_BLOB
    {
    int32_t cbData; //assume dword is a 32 bit int, that is unclear?
    unsigned char* pbData;
    }; //if the year is not 1986, you should not put variables down here

    Ok, now that we can read and understand the actual data type easily....
    sendme is an array of bytes, I poked the integer into the first few bytes (again, due to use of oddball typedef, its unclear how many bytes that integer used), and followed it with the byte data (length is unknown to me, but I assume you know it or how to get it ??). The result is a single buffer that can be sent over a socket or serial port or written to a file or whatever (all this is the same concept!).

    Ok, to reverse it:

    receive(rxbuffer, some_size); //read your file, socket, or whatever here
    dword* dp = (dword*) rxbuffer; // pointer trickery... the first N bytes are the integer portion, so we cast it and extract it.

    CRYPT_DATA_BLOB rxblob;

    rxblob.cbData = dp[0];
    memcpy(rxblob.pbdata, &(rxbuffer[sizeof(dword)], some_size-sizeof(dword));

    ....

    so, you just copy the raw bytes back into a structure of the same type and bam, its there. Your only challenge that I didnt cover is the length of pbdata, which I was unsure of from your code samples.

    Again, memcpy is a bit dangerous. If you prefer you can fool with stringstreams or other safer (but code bloating) tools. You should probably do that if you do not understand pointers VERY WELL. However, if you do not understand pointers very well, you should work hard to get that down so you can do the things that need to be done. I am sure that if you ask, someone can show the the "safe" approach, I am not skilled with the c++ versions and cannot seem to get them into a block of readable, simple, easy to read and easy to write code.

  9. #9
    Join Date
    Jul 2008
    Posts
    69
    Hello Jonnin!

    I did what you suggested to me. I did in the following program:
    Code:
    struct MyBlob
    {
    	DWORD cbData;
    	BYTE* pbData;
    };
    
    
    int main() 
    { 
    		MyBlob sm;
    		BYTE* pbMessage;
    				
    		char sendme[500], MsgToBeSigned[20] = "";
            
            printf(" \n Enter a short Message..."); 
            scanf("%s", MsgToBeSigned); 
    
    
             pbMessage = (BYTE*)(MsgToBeSigned);
    		 sm.pbData =  pbMessage;
    		 sm.cbData = NULL;
    	
    		 memcpy(sendme, sm.cbData, sizeof(DWORD));
    		 memcpy(&sendme[sizeof(DWORD)], sm.pbData, strlen((char*)sm.pbData));
    
    		 
    		 //memcpy( sendme, sm.cbData , sizeof(DWORD));
    		 //memcpy(sendme + sizeof(DWORD) , sm.pbData , strlen((char*)sm.pbData));
    		
            getchar(); 
            getchar(); 
            return 0; 
    
    }
    in both cases (if i uncomment the above two comment lines of memcpy), it give the error : error C2664: 'memcpy' : cannot convert parameter 2 from 'DWORD' to 'const void *'. '

    I think, memcpy can't copy between different data types (Although i have also read about memcpy function that its independent of type). If I convert sm.cbData (DWORD) and sm.pbData (unsigned char) to strings, then it works. I am doing this whole conversion, because i need to send this whole structure MyBlob to receiver and initialize the same strucutre at receiver. This structure (at sender created by a function SignMessage() ) holds digital signature (pb.Data) and its count of bytes (cb.Data). The function verifysignature() at receiver, uses structure of the same kind, initialized with pb.Data and cb.Data received. For that purpose, i used my own method, which is given in the next reply message.

  10. #10
    Join Date
    Jul 2008
    Posts
    69
    At the receiver part (Full code is given at the end), the SignMessage() function gets the message pbMessage (Unsigned Char*) and the address of SignedMessage (of type MyBlob), as given below:
    Code:
     SignMessage(&SignedMessage, pbMessage);
    SignedMessage object now hold the Signature (pbData) and its count of bytes (cbData). I converted both of these two strings, put in one buffer strpbPluscbT using memcpy (I use T as postfix for variables at Transmeter and R for Receiver). lets assume that i transferred it to receiver and stored it in strpbPluscbR. I separated the ingredients strcutre (cbData and pbData). converted these elements to their corresponding data types (DWORD and unsigned char*). initialzed the structure object SignedMessageR.
    Now (please read this part of my message carefully), I compared both the objects SignedMessage and SignedMessageR using the if statement
    Code:
    if(strcmp((char*)SignedMessage.pbData , (char*)SignedMessageR.pbData) == 0 & 
    			((int)SignedMessage.cbData == (int)SignedMessageR.cbData))
    			printf (" \n Structures are same....\n");
    		else
    			printf (" \n Structures are different....");
    The structures are exactly same. If I use SignedMessage in function
    Code:
    VerifySignedMessage(&SignedMessage, &DecodedMessage);
    it works correctly. i mean the decoded message is exactly the same as the original. BUT if i use SignedMessageR instead, then the decoded message is an ureadable text.

    Please if anybody give me some suggestions/hints/guidlines.

    regards,
    Wilayat Khan


    The main code is :

    Code:
    struct MyBlob 
    {
    
    	DWORD cbData;
    	BYTE* pbData;
    };
    
    
    void MyHandleError(LPTSTR psz);
    bool SignMessage(MyBlob *pSignedMessageBlob, unsigned char* pbMessage);
    bool VerifySignedMessage(MyBlob *pSignedMessageBlob , MyBlob *pDecodedMessageBlob);
    
    
    int main() 
    { 
    		MyBlob SignedMessage;
    		MyBlob SignedMessageR;
    		MyBlob DecodedMessage;
    
                             char MsgToBeSigned[50]; 
    		char strcbDataT[5] = "";  //T transmeter, R receiver
    		char strpbDataT[50]= "";
    		char strpbPluscbT[100]= "";
    
    		char strcbDataR[5] = "", strpbDataR[50]= "";
    		char strpbPluscbR[100]= "", recdMsg[6] = "";
    		
    		int intcbDataT, sizeOfcbPluspbT;
    		int intcbDataR;
    
                             BYTE* pbMessage; 
    		
    
            printf(" \n Enter a short Message without spaces..."); 
            scanf("%s", MsgToBeSigned); 
            pbMessage = (BYTE*)(MsgToBeSigned); 
            
            SignMessage(&SignedMessage, pbMessage);
    
    	//////////// Converts DWORD cbData to string //////////////////
    		intcbDataT = (int)SignedMessage.cbData;
        itoa(intcbDataT, strcbDataT,10); //converts integer    intcbDataT 
    //to string strcbDataT   
    		
    		strcpy(strpbDataT, (char*)SignedMessage.pbData); // converts BYTE pbData to string strpbDataT
    		
    	memcpy(strpbPluscbT , strcbDataT, 3);
    	memcpy(strpbPluscbT + 3 , strpbDataT, strlen(strpbDataT));
    		
    	//////////////// strpbPluscbT through CHANNEL...//////////////////
    		SignedMessageR.cbData = 0;
    		SignedMessageR.pbData = NULL;
    		strcpy( strpbPluscbR , strpbPluscbT);
    		//////////////////////////////////////////////////////////////////
    		
    	memcpy(strcbDataR , strpbPluscbR, 3 );  //Separates the cbData
    				
    	memcpy(strpbDataR , strpbPluscbR + 3 , (strlen(strpbPluscbR) - 3));// Separates pbData
    				
    		///////////////Initilize the Structunre now /////////////
    
    		intcbDataR = atoi( strcbDataR ); //converts string strcbDataR to int intcbDataR
    		
    		SignedMessageR.pbData = (BYTE*)strpbDataR;
    		SignedMessageR.cbData = (DWORD)intcbDataR;
    		
    		if(strcmp((char*)SignedMessage.pbData , (char*)SignedMessageR.pbData) == 0 & 
    			((int)SignedMessage.cbData == (int)SignedMessageR.cbData))
    			printf (" \n Structures are same....\n");
    		else
    			printf (" \n Structures are different....");
    
    		//SignedMessage.cbData = 0;
    		//SignedMessage.pbData = NULL;
    
    		//SignedMessage.pbData = SignedMessageR.pbData;
    		//SignedMessage.cbData = SignedMessageR.cbData;
               
    	VerifySignedMessage(&SignedMessageR, &DecodedMessage);
    
    printf(" \n The decoded message is ...%s ", (char*)DecodedMessage.pbData);
    
    	
            //free(SignedMessage.pbData);
       
            getchar(); 
            getchar(); 
            return 0; 
    }

  11. #11
    Join Date
    Dec 2003
    Posts
    3,366
    I will take a look tomorrow...

    did you resolve the compiler problem in your first message where you couldnt memcpy a dword?

  12. #12
    Join Date
    Jul 2008
    Posts
    69
    Yes. When i used the address operator '&' for types other than string, then it work correct when '&' is used with source operand, but it gives memory access error if it is used with destination operand. For see the following code. (the variables are what i have used in my actual program).

    Code:
    memcpy(strpbPluscbT, &SignedMessage.cbData, 3); // 3 is the actual size of cbData all the time in my prog.
    memcpy(strpbPluscbT + 3, &SignedMessage.pbData, strlen((char*)SignedMessage.pbData));
    
    ///////Send the buffer strpbPluscbT through channel////////////////
    
    memcpy(&SignedMessageR.cbData, strpbPluscbT, 3); //copy the first 3 bytes to cbData
    memcpy(&SignedMessageR.pbData, strpbPluscbT + 3, (strlen(strpbPluscbT) - 3)); //copy the rest of buff to pbData

  13. #13
    Join Date
    Dec 2003
    Posts
    3,366
    yes that is a mistake. The name of an array is pointer, so when you take the address of that it is a double pointer (sometimes used in exotic constructs, but here, its a goof). It should not have the & on the destination. I did it on the source to avoid pointer math (your +3) because I find it more explicit (easier to understand intent) to have &(array[3]) than (array+3).


    anyway,
    memcpy(SignedMessageR.cbData, strpbPluscbT, 3); //copy the first 3 bytes to cbData
    memcpy(SignedMessageR.pbData, strpbPluscbT + 3, (strlen(strpbPluscbT) - 3)); //copy the rest of buff to pbData

    should work for you.

    Wait, this is wrong too
    memcpy(strpbPluscbT + 3, &SignedMessage.pbData, strlen((char*)SignedMessage.pbData));
    should be
    memcpy(strpbPluscbT + 3, SignedMessage.pbData, strlen((char*)SignedMessage.pbData));

    Same issue.
    Last edited by jonnin; 08-27-2008 at 12:27 PM.

  14. #14
    Join Date
    Dec 2003
    Posts
    3,366
    finally, if you are going to treat them as strings, remember that you need to have the zero terminal copied. I forget if strlen does this automatically or not, but to be safe make the next location of the string zero explicitly or, better still, use strcpy instead of memcpy. I thought you had raw bytes (could have a zero anywhere in it) not ascii data, so I said memcpy. If its just text, strcpy will handle the zero terminal for you & clean the code up.

  15. #15
    Join Date
    Jul 2008
    Posts
    69
    Thanks Jonnine for your effort.

    I think you did not read my replies 9 and 10 carefull. in reply 9 I have mentioned that if i dont use & operator with SignedMessage.pbData or SignedMessage.cbData then it gives type mismathc error: like, error C2664: 'memcpy' : cannot convert parameter 2 from 'DWORD' to 'const void *'. '

    Your fear that memcpy may not work correctly, is wrong. If i copy one structure in another using memcpy it works.

    Your suggestion of using strcpy, is good but I have already applied it. see my repy 10. In that reply, if you see, i have mentioned, after i convert each element of SignedMessageT structure to strings, then combining, and then re-separating their elements, and finaly if i initialize a new structure variable with that, and pass it to VerifySignedMessage() function, it dont work. Although, as i mentioned before, i compared the new generated structure with the orignal returned by SignedMessage(), They both are 100% same. ( i compared element by element, displayed its elements, compared its sizes, so on), but if i pass the orignal structure to function VerifySignedMessage(), it works, but i pass the new one, it dont work.

    if I initialze the new structure by copying old one to new one using memcpy, and pass the new one to VerifySignedMessage(), it correctly works. e.g.

    memcpy(&SignedMessageR , &SignedMessageT, sizeof(SignedMessageT));

Similar Threads

  1. Gradebook program
    By [gx]Shadow in forum Java
    Replies: 5
    Last Post: 10-25-2006, 11:20 PM
  2. Replies: 9
    Last Post: 07-28-2005, 09:40 PM
  3. Replies: 0
    Last Post: 10-11-2002, 11:52 AM
  4. Altering created Distinct Data Type
    By Sindhu in forum Database
    Replies: 0
    Last Post: 12-06-2001, 12:28 PM
  5. Numeric data type
    By Vhost in forum Database
    Replies: 1
    Last Post: 03-28-2001, 09:38 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center