Pelles C forum

Assembly language => Assembly discussions => Topic started by: Vortex on February 23, 2025, 08:17:07 PM

Title: Base64 encoding\decoding
Post by: Vortex on February 23, 2025, 08:17:07 PM
Here is an example using cryptographic API functions to encode to base64 format and decode the result :

.386
.model flat,stdcall
option casemap:none

include     Base64.inc

.data

MyStr       db 'This is a test.',0
m1          db 'String MyStr converted to base64 = ',0
m2          db 13,10,'Base64 data BinData converted to string = ',0
binSize     dd STRING_SIZE
MyStr2size  dd STRING_SIZE

.data?

BinData     db STRING_SIZE dup(?)
MyStr2      db STRING_SIZE dup(?)

.code

start:

    invoke  lstrlen,ADDR MyStr
    invoke  CryptBinaryToString,ADDR MyStr,eax,\
            CRYPT_STRING_BASE64,ADDR BinData,\
            ADDR binSize

    invoke  StdOut,ADDR m1
    invoke  StdOut,ADDR BinData

    invoke  CryptStringToBinary,ADDR BinData,0,\
            CRYPT_STRING_BASE64,ADDR MyStr2,\
            ADDR MyStr2size,0,0

    invoke  StdOut,ADDR m2
    invoke  StdOut,ADDR MyStr2

    invoke  ExitProcess,eax

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

StdOut PROC _string:DWORD

    sub     esp,2*4
   
    invoke  GetStdHandle,STD_OUTPUT_HANDLE
    mov     DWORD PTR [esp+4],eax
   
    invoke  lstrlen,DWORD PTR [esp+12]
    mov     edx,esp
   
    invoke  WriteFile,DWORD PTR [esp+20],\
            DWORD PTR [esp+24],\
            eax,edx,0
           
    add     esp,2*4
    retn    4

StdOut ENDP

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

END start
Title: Re: Base64 encoding\decoding
Post by: John Z on February 23, 2025, 09:28:22 PM
Hi Vortex,

This is very interesting, and coincidentally, I just ran across the crypto section of the API.  Before this week I had no idea such a thing existed.   While I learned a lot by writing my own Base64 encode/decode routines I see using the API would be simpler and probably run faster although I must say mine is no slow poke.

Thanks,

John Z
Title: Re: Base64 encoding\decoding
Post by: Vortex on February 24, 2025, 10:07:21 AM
Hi John,

This is the C code obtained from the BCX converter :

#include <windows.h>
#include <stdio.h>

#pragma comment(lib, "crypt32.lib")

#define STRSIZE 512

static char    BinData[STRSIZE];
static char    MyStr[STRSIZE];
static char    MyStr2[STRSIZE];
static DWORD  binSize=STRSIZE;
static DWORD  MyStr2size=STRSIZE;

int main(int argc, char *argv[])
{
  strcpy(MyStr,"This is a test.");
  CryptBinaryToString((const unsigned char*)MyStr,(int)strlen(MyStr),CRYPT_STRING_BASE64,(char*)BinData, &binSize);
  printf("%s%s\n","String MyStr converted to base64 = ",BinData);
  CryptStringToBinary(BinData,0,CRYPT_STRING_BASE64,(unsigned char*)&MyStr2, &MyStr2size,0,0);
  printf("%s%s\n","Base64 data BinData converted to string = ",MyStr2);
  return EXIT_SUCCESS;  // End of main program
  }
Title: Re: Base64 encoding\decoding
Post by: TimoVJL on February 24, 2025, 03:00:30 PM
Long time ago there was need for base64 conversion, but at that time have to support Windows 9* and AIX for SMTP too.
Windows XP with this or CDOSys made things easier.
Title: Re: Base64 encoding\decoding
Post by: Vortex on February 24, 2025, 07:52:48 PM
Hi Timo,

The Windows tool certutil can do base64 coding \ encoding.
Title: Re: Base64 encoding\decoding
Post by: John Z on February 24, 2025, 09:04:11 PM
Thanks Vortex,
Quote from: Vortex on February 24, 2025, 10:07:21 AM
Hi John,
This the C code obtained from the BCX converter :

A slight flaw to catch the unaware in the above C example.  The output of CRYPT_STRING_BASE64 is a minimum of 33% larger than the input string.  Not a problem with converter code since the input string was so small. But for the example given if the input string was over 385 or so bytes - then buffer overrun.

John Z
Title: Re: Base64 encoding\decoding
Post by: Quin on April 28, 2025, 05:00:07 PM
Cool stuff, thanks for sharing Vortex! I really like this API, leave it to Microsoft to have base64 encoding/decoding hidden in their Win32 API. 8)