Data Encryption Business Function

Is there anyway to find this API for Decode B64 , I searched online couldn't find the exact required I/O details and also searching API's for JDE is a task that never goes in a desired direction. I remember a discussion in JDE list to maintain a API repository, is there anything available like that, would be lot useful.
 
Is there anyway to find this API for Decode B64

I assume you mean documentation? Not sure there is any, but a lot of times you can figure it out from the function signature with a little experimentation or if you are lucky find an example in pristine code. If you have Intellisense working for JDE C BSFN development you can quickly see the function sig. Otherwise just do a text search in the jde system header files for the api call to view the function definition. decodeB64 is defined in jdelprto.h and looks like

Code:
LIB_RTN(int)	JDEWINAPI decodeB64(BYTE *pBinaryBuf, int *pnBinaryLen, JCHAR *szB64String);

Just looking at it I think it would work like the following:

JCHAR *szB64String
This is obviously the null terminated base64 string to pass in.

BYTE *pBinaryBuf, int *pnBinaryLen
I DONT think decodeB64 allocates the buffer for you otherwise the param would be BYTE **pBinaryBuf. So, I think YOU need to provide a buffer to output the contents to and pass the size of the buffer. But since the size of the buffer (pnBinaryLen) is passed as a pointer, if the buffer and size you pass is too small to hold the data my guess is that decodeB64 doesn't decode the data but instead returns the size of the buffer needed to hold the decode the data in *pnBinaryLen. In fact you may be able to pass NULL and 0 for buf/size along with the string to decode on the first call to get the size of the buffer you need, then allocate the buffer and pass everything in on the second call to actually decode the base64 data to your buffer. Something like:

Code:
BYTE  *pMyBuf = (BYTE *)NULL;
int nBufSize = 0;

decodeB64(NULL, &nBufSize, szBase64StringToDecode);
pMyBuf = jdeAlloc(COMMON_POOL, nBufSize, MEM_ZEROINIT);
decodeB64(pMyBuf, &nBufSize, szBase64StringToDecode);
...
jdeFree(pMyBuf);

This is just a guess based on the function sig. This is where I would start experimenting...

BTW, just read your question above and it said that the binary data that will be decoded is actually a string so you expect to get a string back. More than likely the sender of the data doesn't care that you are using C so probably does NOT include the null termination char, so your code would probably look like:


Code:
ZCHAR  *pMyBuf = (ZCHAR *)NULL;
int nBufSize = 0;

decodeB64(NULL, &nBufSize, szBase64StringToDecode);
pMyBuf = jdeAlloc(COMMON_POOL, nBufSize + sizeof(ZCHAR), MEM_ZEROINIT);
decodeB64((BYTE *)pMyBuf, &nBufSize, szBase64StringToDecode);
...
jdeFree(pMyBuf);
 
Last edited:
Hi Brian,

I tested this code using the API:

Code:
````
ZCHAR *pMyBuf = (ZCHAR *)NULL;
int nBufSize = 0;

decodeB64(NULL, &nBufSize, lpDS->szInputString);
pMyBuf = jdeAlloc(COMMON_POOL, nBufSize * sizeof(ZCHAR), MEM_ZEROINIT);
decodeB64((BYTE *)pMyBuf, &nBufSize, lpDS->szInputString);

jdeFree(pMyBuf);
````

but when I test this using a application(Local fatclient) or using object browser, JDE crashes after passing through "jdeAlloc",
it says:Access violation writing location 0x0AD80400
Any ides why this is happening.

on the other hand, if i have to use the BSFN you had uploaded, what would be the input and output parameters for the calling bsfn? and do i get the string output?
 
Did you debug? Main thing is to see if my assumption is correct that decodeB64 will return the size needed if NULL,0 is passed, so watch the value of nBufSize after the first call to decodeB64. If still zero after first call you will have to determine the size of the buffer in advance and only call decodeB64 once. I think there is a macro in the BSFN I attached that will determine output buffer size based on the input string. Otherwise you could just over allocate the buffer. The buffer needed s/b smaller than the input string.


BTW, code above s/b
nBufSize * sizeof(JCHAR)
sb
nBufSize + sizeof(JCHAR)

...most of the time when allocating it is * sizeof... muscle memory...

Also you probably will want to trim lpDS->szInputString since JDE will pad it with spaces on the end when passed from ER code. Not sure that it matters but probably to be safe should trim it.

Again, I have never used this API call so this is all assumption on my part, you will have to play around with it to get it to work.
 
Curiosity got the better of me. decodeB64 will NOT return the buffer size needed if the size passed is to small like I assumed it would. At first I didn't think that made any sense, but it does. I think it returns the size of the binary decoded which does make sense (and I think I effectively did the same in my BSFN). So you will need to allocate a buffer big enough BEFORE calling decodeB64. There are macros in the BSFN I posted above to calc size (I58FUP02_b64_CalcEncodedBufSize and I58FUP02_b64_CalcBinBufSize). I have expended those macros in the code below which I compiled, ran and appears to work.


Code:
	ZCHAR		*pszStringToEncode = "The quick brown fox jumps over the lazy dog",
				*pszBuf = (ZCHAR *)NULL;
	JCHAR		*pszEncodedB64 = (JCHAR *)NULL,
				szStringOut[501] = {0};
	int		nEncodedSize = 0,
				nBinSize = 0,
				nBufSize = 0;


	/***** Encode a String *****/
	nBinSize = jdeZStrlen(pszStringToEncode);
	nEncodedSize = (((nBinSize) + 2 - (((nBinSize) + 2) % 3)) / 3 * 4) + sizeof(ZCHAR);
	pszEncodedB64 = jdeAlloc(COMMON_POOL, nEncodedSize * sizeof(JCHAR), MEM_ZEROINIT);
	encodeB64((BYTE *)pszStringToEncode, nBinSize, pszEncodedB64, nEncodedSize);
	

	/*****  Decode *****/
	nBufSize = ((((nEncodedSize) / 4) + ((nEncodedSize) % 4 != 0 ? 1:0)) * 3) + sizeof(ZCHAR);
	pszBuf = jdeAlloc(COMMON_POOL, nBufSize, MEM_ZEROINIT);
	decodeB64((BYTE *)pszBuf, &nBufSize, pszEncodedB64);
	jdeToUnicode(szStringOut, pszBuf, DIM(szStringOut), NULL);


	/* free resources */
	jdeFree(pszEncodedB64);
	jdeFree(pszBuf);
 
Last edited:
The code in the above reply works like a charm. But still there is one issue when we are working with the Byte output of the API. I guess the Byte is not able to handle the character è so this is getting converted into Ã'' . The base64 string to decode is QkhLTCBDb21taXNzaW9ucyAzw6htZSBUciAyMDE5LnBkZg==?= and the correct decode for this is: BHKL Commissions 3ème Tr 2019.pdf but what is got is: BHKL Commissions 3ème Tr 2019.pdf

it is just one character error but still the client is not happy as they will search with the exact name it seems.
do you think this will work using the Base64 BSFN you had uploaded or is this something JDE can't handle.
 
decodeB64 appears to want the input string to use UTF8 encoding and "QkhLTCBDb21taXNzaW9ucyAzw6htZSBUciAyMDE5LnBkZg==?=" appears to be something other than that based on the expected result (possibly ISO-8859-1). Its possible that whoever is sending you this string is using UTF8 but somewhere between them and the call to the BSFN (as part of the process to convert to unicode) it is getting transcoded to ISO-8859-1. Don't know exactly what is going on but I believe you have a character encoding problem with the B64 input string.
 
Last edited:
I don't think so the issue is with UTF8 encoded or not. Because I even tried using the online base64 converter to get the Base64 encode for BHKL Commissions 3ème Tr 2019.pdf and used it in Base64 API and it gave me the wrong output: BHKL Commissions 3ème Tr 2019.pdf
for now however in the bsfn at the output I'm using string replace to replace è to è if it exists. May be later will build a list of unhanded characters by bytes and call a new BSFN to replace all those. however wondering how to get that list!
 
That approach is not going to work. I think you have a fundamental misunderstanding about base 64 encoding. The reason you are getting the wrong character in the output is because the input is not being interpreted correctly, decodeB64 is expecting a different code page for the character set (I may have gotten it reversed, it may be expecting ISO-8859 and UTF8 is being passed). There are not "unhanded" characters in the output - if you were decoding a jpg, an excel spreadsheet (or an encrypted string which was the topic of this thread to begin with) instead of a simple string you couldn't simply replace "unhanded" characters. If you substitute "..quick brown fox..." in the example above with your expected output "BHKL Commissions 3ème Tr 2019.pdf" you get the following as the encoded string:

Code:
QkhLTCBDb21taXNzaW9ucyAz6G1lIFRyIDIwMTkucGRm

Paste that into https://www.base64decode.org/, select ISO-8859-1 as the character set and decode and you will get your expected output, which, is the same output you get in the example code above when passed to decodeB64.

Now, go back to https://www.base64decode.org/ and paste your original encoded b64 string

Code:
QkhLTCBDb21taXNzaW9ucyAzw6htZSBUciAyMDE5LnBkZg==?=

Leave the character set as ISO-8859-1 and you get "BHKL Commissions 3ème Tr 2019.pdf". Now switch the character set to UTF-8 and you get "BHKL Commissions 3ème Tr 2019.pdf"


You are passing a UTF-8 character set encoded string to decodeB64 and it is expecting ISO-8859-1.

Edit:
This is incorrect, see post below. I had a misunderstanding about B64 encoding. Characterset doesn't matter to B64 encoding.
 
Last edited:
My string was UTF8 i was sure about that, so the API is expecting ISO-8859-1, so need to find an alternate solution.
 
There may be a workaround to still do it in JDE but I would have to think about it. Not sure if you could simply transcode (convert) the b64 encoded string from UTF8 to ISO-8859-1 before passing to decodeB64 or not. The BSFN that I posted also wants ISO-8859-1 as well. Guess I should have made my BSFN like the link I posted and allow user to determine the character set. :)
 
So I did get to thinking about it and my apologies ashwin E1. I think you were right. You do need to transcode the output. Base64 doesn't care about the input character set because it only uses the first 0-127 characters which, regardless of the charset, are all coded the same (ASCII). In the case of a string output like what you are doing you do need to the know the character set of the original source and transcode it. The following code should work for you. Notice the API call to jdeToUnicode, that is all that really changed.

Code:
	ZCHAR		*pszBuf = (ZCHAR *)NULL;
	JCHAR		*pszEncodedB64 = _J("QkhLTCBDb21taXNzaW9ucyAzw6htZSBUciAyMDE5LnBkZg==?="),
				szStringOut[501] = {0};
	int		nEncodedSize = 0,
				nBufSize = 0;


	/*****  Decode *****/
	nEncodedSize = jdeStrlen(pszEncodedB64);
	nBufSize = ((((nEncodedSize) / 4) + ((nEncodedSize) % 4 != 0 ? 1:0)) * 3) + sizeof(ZCHAR);
	pszBuf = jdeAlloc(COMMON_POOL, nBufSize, MEM_ZEROINIT);
	decodeB64((BYTE *)pszBuf, &nBufSize, pszEncodedB64);
	jdeToUnicode(szStringOut, pszBuf, DIM(szStringOut), _J("UTF8"));

	/* free resources */
	jdeFree(pszBuf);
 
Back
Top