[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 328
  • Last Modified:

Need a small function added

Hi,

Below you will see a code. I'm trying to convert some VB code into C++ and below is a start that I found on the Internet (it uses Crypt32.Lib) - It's ready, except for a few feautres. The "job" is to add the missing features below to the c++ code. These are the features:

1. User enters string through parameter, for example: 'hello'
Then in VB, somethine like "Chr$(0)" is being added at the end of that string. I'm not sure what Chr$(0) is though.

2. Now we have a string.
This string should now be base64 encoded.

3. With the new base64 encoded string, the VB program does the following (where sData is the base64 encoded string, and DataIn is a DATA_BLOB, see C++ source)

    Dim abytFileData()   As Byte
    Dim abytDataOut()    As Byte
    abytFileData = StrConv(sData, vbFromUnicode) & Chr$(0)
    DataIn.cbData = UBound(abytFileData) + 1
    DataIn.pbData = VarPtr(abytFileData(0))

Now Im not sure what it does, but I believe it puts the encoded base64 string into a ByteArray, and then
it sets a length (?) of that ByteArray at the DataIn.cbData, and a pointer (?) at DataIn.pbdata to the ByteArray. Riiight?

4. Once that is done, it calls the function CryptProtectData, which is already programmed below.

5. Once it has called the function, VB does the following with the result:

ReDim abytDataOut(DataOut.cbData) As Byte
Call CopyMemory(DataOut(0), ByVal DataOut.pbData, DataOut.cbData)

Result = Chr$(3) & Chr$(4) & StrConv(abytDataOut, vbUnicode)

6. "Result" is now the result that I am looking for.

Any Idea how to get to that result?

So in summary, all I need is going from a User Input, to encoding that Input into base64, then using that to put it in a ByteArray, which is being used by a data_blob (DataIn), and then the data_blob is being used by CryptProtectData.

I would've given more points if possible. But if anyone is able to figure it out, I will appreciate a lot!

-- Here is the c++ code that I already have (requires crypt32.lib)

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

void MyHandleError(char *s);

void main()
{
    DATA_BLOB DataIn;
    DATA_BLOB DataOut;
    DATA_BLOB DataVerify;
    BYTE *pbDataInput =(BYTE *)"Hello world of data protection.";
    DWORD cbDataInput = strlen((char *)pbDataInput)+1;
    DataIn.pbData = pbDataInput;    
    DataIn.cbData = cbDataInput;
    CRYPTPROTECT_PROMPTSTRUCT PromptStruct;
    LPWSTR pDescrOut = NULL;

    printf("The data to be encrypted is: %s\n",pbDataInput);

    if(CryptProtectData(
        &DataIn,
        NULL,
        NULL,
        NULL,
        NULL,
        0,
        &DataOut))
    {
        printf("The encryption phase worked. \n");
    }
    else
    {
        MyHandleError("Encryption error!");
    }

    LocalFree(pDescrOut);
    LocalFree(DataOut.pbData);
}

void MyHandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
}
0
TonyJiz
Asked:
TonyJiz
  • 2
2 Solutions
 
jkrCommented:
Basically, that's the sample from http://msdn.microsoft.com/library/en-us/seccrypto/security/example_c_program_using_cryptprotectdata.asp ("Example C Program: Using CryptProtectData"), all you need to do is adding the parameters, i.e. like

void EncryptData(BYTE* pIn, size_t szIn,BYTE* pOut, size_t szOut)
{
    DATA_BLOB DataIn;
    DATA_BLOB DataOut;
    DATA_BLOB DataVerify;
    BYTE *pbDataInput =(BYTE *)"Hello world of data protection.";
    DWORD cbDataInput = strlen((char *)pbDataInput)+1;
    DataIn.pbData = pIn;    
    DataIn.cbData = szIn;

    if(CryptProtectData(
        &DataIn,
        NULL,
        NULL,
        NULL,
        NULL,
        0,
        &DataOut))
    {
        printf("The encryption phase worked. \n");
    }
    else
    {
        MyHandleError("Encryption error!");
    }

    if (szOut >= DataOut.cbData)
        CopyMemory(pOut,DataOut.pbData,DataOut.cbData);
        else
        MyHandleError("Buffer too small!");

    LocalFree(DataOut.pbData);
}
0
 
Knut HunstadCommented:
CHR$(0) is the same as '\0' in C++, the null character, marking the end of a C-style string. A common thing to have to remember when converting between Basic and C/C++.
0
 
jkrCommented:
I am not really sure if I should agree to a split here, since the code covers the issue completely...
0
 
TonyJizAuthor Commented:
I appreciate the help from this site,

but how could you say that the code covers the issue completely?

All you did was quoting my code and putting it into a procedure.
Did you even read about the base64 encoding, the data blob, the string conversions and the other steps that needed to be done?

I eventually had this question solved by someone else at Delphi. The comments above just weren't worth giving points too since they were far from the solution.

I will split the points though since the comment about the chr(0) did help me, but it was only the solution of the first step and not the others.
Greeting.
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now