-
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
-
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.
-
I agree with jonnin's opinion. Naming convention of Microsoft is pretty confused.
-
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
-
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, ...);
-
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.
-
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
-
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.
-
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.
-
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;
}
-
I will take a look tomorrow...
did you resolve the compiler problem in your first message where you couldnt memcpy a dword?
-
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
-
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 11:27 AM.
-
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.
-
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
-
By [gx]Shadow in forum Java
Replies: 5
Last Post: 10-25-2006, 10:20 PM
-
Replies: 9
Last Post: 07-28-2005, 08:40 PM
-
Replies: 0
Last Post: 10-11-2002, 10:52 AM
-
By Sindhu in forum Database
Replies: 0
Last Post: 12-06-2001, 12:28 PM
-
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
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|