diff --git a/src/include/base64.pas b/src/include/base64.pas new file mode 100644 index 00000000..aa2103ca --- /dev/null +++ b/src/include/base64.pas @@ -0,0 +1,195 @@ +{ + Include->Base64 - Base64 encode and decode. + + @author(Angus C <angus@actm.uk>) +} + +unit base64; + +interface + +uses + lmemorymanager, + strings, + util; + +const + base64_enc_map : array[0..63] of char = ('A','B','C','D','E', + 'F','G','H','I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X','Y','Z','a', + 'b','c','d','e','f','g','h','i','j','k','l', + 'm','n','o','p','q','r','s','t','u','v','w', + 'x','y','z','0','1','2','3','4','5','6','7', + '8','9','+','/'); + +function b64_encode(src : PuInt8; len : uInt32; out_len : PuInt32) : PuInt8; +function b64_decode(src : PuInt8; len : uInt32; out_len : PuInt32) : PuInt8; + +function b64_encode_str(src : PChar) : PChar; +function b64_decode_str(src : PChar) : PChar; + +implementation + +function b64_encode(src : PuInt8; len : uInt32; out_len : PuInt32) : PuInt8; +var + olen : uInt32; + line_len : uInt32; + b64end : PuInt8; + b64in : PuInt8; + b64pos : PuInt8; + output : PuInt8; + +begin + olen := len * 4 div 3 + 4; // 3-byte blocks to 4-byte + olen := olen + (olen div 72); // line feeds + olen := olen + 1; // nul termination + + output := nil; + if olen < len then begin + // integer overflow + end else begin + output := PuInt8(kalloc(olen)); + b64end := PuInt8(uInt32(src) + uInt32(len)); + b64in := src; + b64pos := output; + line_len := 0; + while (uInt32(b64end) - uInt32(b64in)) >= 3 do begin + b64pos^ := uInt8(base64_enc_map[b64in[0] shr 2]); + inc(b64pos); + b64pos^ := uInt8(base64_enc_map[((b64in[0] and $03) shl 4) or (b64in[1] shr 4)]); + inc(b64pos); + b64pos^ := uInt8(base64_enc_map[((b64in[1] and $0F) shl 2) or (b64in[2] shr 6)]); + inc(b64pos); + b64pos^ := uInt8(base64_enc_map[b64in[2] and $3F]); + inc(b64pos); + inc(b64in, 3); + inc(line_len, 4); + if line_len >= 72 then begin + b64pos^ := $0A; + inc(b64pos); + end; + end; + + if (uInt32(b64end) - uInt32(b64in)) > 0 then begin + b64pos^ := uInt8(base64_enc_map[b64in[0] shr 2]); + inc(b64pos); + if (uInt32(b64end) - uInt32(b64in)) = 1 then begin + b64pos^ := uInt8(base64_enc_map[((b64in[0] and $03) shl 4)]); + inc(b64pos); + b64pos^ := $3D; + inc(b64pos); + end else begin + b64pos^ := uInt8(base64_enc_map[((b64in[0] and $03) shl 4) or (b64in[1] shr 4)]); + inc(b64pos); + b64pos^ := uInt8(base64_enc_map[((b64in[1] and $0F) shl 2)]); + inc(b64pos); + end; + b64pos^ := $3D; + inc(b64pos); + inc(line_len, 4); + end; + + if line_len > 0 then begin + b64pos^ := $0A; + inc(b64pos); + end; + b64pos^ := $0; + if out_len <> nil then begin + out_len^ := uInt32(b64pos) - uInt32(output); + end; + end; + b64_encode := output; +end; + +function b64_decode(src : PuInt8; len : uInt32; out_len : PuInt32) : PuInt8; +var + b64tmp : uInt8; + b64pos : PuInt8; + output : PuInt8; + i : uInt32; + count : uInt32; + olen : uInt32; + pad : uInt32; + dtable : array[0..255] of uInt8; + block : array[0..3] of uInt8; + +begin + pad := 0; + memset(uInt32(@dtable[0]), $80, 256); + + for i := 0 to (sizeof(base64_enc_map) - 2) do begin + dtable[uInt8(base64_enc_map[i])] := uInt8(i); + end; + dtable[uInt8('=')] := 0; + + count := 0; + for i := 0 to (len - 1) do begin + if dtable[uInt8(src[i])] <> $80 then begin + inc(count) + end; + end; + if count = 0 or count mod 4 then begin + // something went wrong + end else begin + olen := count div 4 * 3; + b64pos := PuInt8(kalloc(olen)); + output := b64pos; + if output = nil then begin + // something went wrong + end else begin + count := 0; + for i := 0 to (len - 1) do begin + b64tmp := uInt8(dtable[src[i]]); + if b64tmp = $80 then begin + continue; + end; + if src[i] = uInt8('=') then begin + inc(pad); + end; + block[count] := b64tmp; + inc(count); + if count = 4 then begin + b64pos^ := uInt8((block[0] shl 2) or (block[1] shr 4)); + inc(b64pos); + b64pos^ := uInt8((block[1] shl 4) or (block[2] shr 2)); + inc(b64pos); + b64pos^ := uInt8((block[2] shl 6) or block[3]); + inc(b64pos); + count := 0; + if pad > 0 then begin + if pad = 1 then begin + dec(b64pos); + end else if pad = 2 then begin + dec(b64pos, 2); + end else begin + kfree(void(output)); + b64_decode := nil; + exit; + end; + break; + end; + end; + end; + end; + out_len^ := uInt32(b64pos) - uInt32(output); + end; + b64_decode := output; +end; + +function b64_encode_str(src : PChar) : PChar; +var + src_len : uInt32; +begin + src_len := stringSize(src); + b64_encode_str := PChar(b64_encode(PuInt8(src), src_len, nil)); +end; + +function b64_decode_str(src : PChar) : PChar; +var + src_len : uInt32; +begin + src_len := stringSize(src); + b64_decode_str := PChar(b64_decode(PuInt8(src), src_len, nil)); +end; + +end. \ No newline at end of file diff --git a/src/include/md5.pas b/src/include/md5.pas index e891ebeb..e3b92fac 100644 --- a/src/include/md5.pas +++ b/src/include/md5.pas @@ -1,3 +1,10 @@ +{ + Include->MD5 - MD5 checksum. + + @author(Angus C <angus@actm.uk>) + @author(Kieron Morris <kjm@kieronmorris.me>) +} + unit md5; interface diff --git a/src/kernel.pas b/src/kernel.pas index fb93c398..d499b639 100644 --- a/src/kernel.pas +++ b/src/kernel.pas @@ -46,7 +46,10 @@ uses edit, udpcat, cpu, - md5, md5sum, + md5, + md5sum, + base64, + base64_prog, rand; procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall; @@ -227,6 +230,7 @@ begin edit.init(); udpcat.init(); md5sum.init(); + base64_prog.init(); terminal.run(); { Init Splash } diff --git a/src/prog/base64_prog.pas b/src/prog/base64_prog.pas new file mode 100644 index 00000000..d83cbfff --- /dev/null +++ b/src/prog/base64_prog.pas @@ -0,0 +1,66 @@ +{ + Prog->Base64 - Base64 encode and decode. + + @author(Angus C <angus@actm.uk>) +} +unit base64_prog; + +interface + +uses + console, terminal, keyboard, util, strings, tracer, base64, lmemorymanager; + +procedure init(); + +implementation + +procedure run(Params : PParamList); +var + input : pchar; + pinput : pchar; + encdec : pchar; + result : pchar; + i : uInt32; + PSize : uInt32; + +begin + tracer.push_trace('base64_prog.run'); + if paramCount(Params) > 1 then begin + encdec := getParam(0, Params); + if stringEquals(encdec, 'encode') then begin + PSize := 0; + for i := 1 to ParamCount(params) - 1 do begin + PSize := PSize + stringSize(getParam(i, Params)); + end; + Psize := PSize + 1 + (ParamCount(params) - 1); + input := pchar(kalloc(PSize)); + pinput := input; + for i := 1 to ParamCount(params) - 1 do begin + memcpy(uInt32(getParam(i, Params)), uInt32(pinput), stringSize(getParam(i, Params))); + inc(pinput, stringSize(getParam(i, Params))); + pinput^ := ' '; + inc(pinput); + end; + dec(pinput); + pinput^ := #0; + result := b64_encode_str(input); + writestringlnWND(result, getTerminalHWND); + kfree(void(result)); + end else if stringEquals(encdec, 'decode') then begin + input := getParam(1, Params); + result := b64_decode_str(input); + writestringlnWND(result, getTerminalHWND); + kfree(void(result)); + end else writestringlnWND('Usage: base64 <encode/decode> <text>', getTerminalHWND); + end else begin + writestringlnWND('Usage: base64 <encode/decode> <text>', getTerminalHWND); + end; +end; + +procedure init(); +begin + tracer.push_trace('base64_prog.init'); + terminal.registerCommand('BASE64', @Run, 'Perform Base64 Encode/Decode.'); +end; + +end. \ No newline at end of file