Rearranged wasm challenge utils

This commit is contained in:
WeebDataHoarder
2025-04-06 12:51:27 +02:00
parent 65561ab00e
commit 02f3c1cb19
12 changed files with 149 additions and 125 deletions

View File

@@ -0,0 +1,118 @@
package _interface
import (
"encoding/json"
"git.gammaspectra.live/git/go-away/utils/inline"
)
// Allocation is a combination of pointer location in WASM memory and size of it
type Allocation uint64
func NewAllocation(ptr, size uint32) Allocation {
return Allocation((uint64(ptr) << uint64(32)) | uint64(size))
}
func (p Allocation) Pointer() uint32 {
return uint32(p >> 32)
}
func (p Allocation) Size() uint32 {
return uint32(p)
}
func MakeChallengeDecode(callback func(in MakeChallengeInput, out *MakeChallengeOutput), in Allocation) (out Allocation) {
outStruct := &MakeChallengeOutput{}
var inStruct MakeChallengeInput
inData := PtrToBytes(in.Pointer(), in.Size())
err := json.Unmarshal(inData, &inStruct)
if err != nil {
outStruct.Code = 500
outStruct.Error = err.Error()
} else {
outStruct.Code = 200
outStruct.Headers = make(inline.MIMEHeader)
func() {
// encapsulate err
defer func() {
if recovered := recover(); recovered != nil {
if outStruct.Code == 200 {
outStruct.Code = 500
}
if err, ok := recovered.(error); ok {
outStruct.Error = err.Error()
} else {
outStruct.Error = "error"
}
}
}()
callback(inStruct, outStruct)
}()
}
if len(outStruct.Headers) == 0 {
outStruct.Headers = nil
}
outData, err := json.Marshal(outStruct)
if err != nil {
panic(err)
}
return NewAllocation(BytesToLeakedPtr(outData))
}
func VerifyChallengeDecode(callback func(in VerifyChallengeInput) VerifyChallengeOutput, in Allocation) (out VerifyChallengeOutput) {
var inStruct VerifyChallengeInput
inData := PtrToBytes(in.Pointer(), in.Size())
err := json.Unmarshal(inData, &inStruct)
if err != nil {
return VerifyChallengeOutputError
} else {
func() {
// encapsulate err
defer func() {
if recovered := recover(); recovered != nil {
out = VerifyChallengeOutputError
}
}()
out = callback(inStruct)
}()
}
return out
}
type MakeChallengeInput struct {
Key []byte
Parameters map[string]string
Headers inline.MIMEHeader
Data []byte
}
type MakeChallengeOutput struct {
Data []byte
Code int
Headers inline.MIMEHeader
Error string
}
type VerifyChallengeInput struct {
Key []byte
Parameters map[string]string
Result []byte
}
type VerifyChallengeOutput uint64
const (
VerifyChallengeOutputOK = VerifyChallengeOutput(iota)
VerifyChallengeOutputFailed
VerifyChallengeOutputError
)

View File

@@ -0,0 +1,10 @@
//go:build !tinygo || !wasip1
package _interface
func PtrToBytes(ptr uint32, size uint32) []byte { panic("not implemented") }
func BytesToPtr(s []byte) (uint32, uint32) { panic("not implemented") }
func BytesToLeakedPtr(s []byte) (uint32, uint32) { panic("not implemented") }
func PtrToString(ptr uint32, size uint32) string { panic("not implemented") }
func StringToPtr(s string) (uint32, uint32) { panic("not implemented") }
func StringToLeakedPtr(s string) (uint32, uint32) { panic("not implemented") }

View File

@@ -0,0 +1,59 @@
//go:build tinygo
package _interface
// #include <stdlib.h>
import "C"
import (
"unsafe"
)
// PtrToBytes returns a byte slice from WebAssembly compatible numeric types
// representing its pointer and length.
func PtrToBytes(ptr uint32, size uint32) []byte {
return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(ptr))), size)
}
// BytesToPtr returns a pointer and size pair for the given byte slice in a way
// compatible with WebAssembly numeric types.
// The returned pointer aliases the slice hence the slice must be kept alive
// until ptr is no longer needed.
func BytesToPtr(s []byte) (uint32, uint32) {
ptr := unsafe.Pointer(unsafe.SliceData(s))
return uint32(uintptr(ptr)), uint32(len(s))
}
// BytesToLeakedPtr returns a pointer and size pair for the given byte slice in a way
// compatible with WebAssembly numeric types.
// The pointer is not automatically managed by TinyGo hence it must be freed by the host.
func BytesToLeakedPtr(s []byte) (uint32, uint32) {
size := C.ulong(len(s))
ptr := unsafe.Pointer(C.malloc(size))
copy(unsafe.Slice((*byte)(ptr), size), s)
return uint32(uintptr(ptr)), uint32(size)
}
// PtrToString returns a string from WebAssembly compatible numeric types
// representing its pointer and length.
func PtrToString(ptr uint32, size uint32) string {
return unsafe.String((*byte)(unsafe.Pointer(uintptr(ptr))), size)
}
// StringToPtr returns a pointer and size pair for the given string in a way
// compatible with WebAssembly numeric types.
// The returned pointer aliases the string hence the string must be kept alive
// until ptr is no longer needed.
func StringToPtr(s string) (uint32, uint32) {
ptr := unsafe.Pointer(unsafe.StringData(s))
return uint32(uintptr(ptr)), uint32(len(s))
}
// StringToLeakedPtr returns a pointer and size pair for the given string in a way
// compatible with WebAssembly numeric types.
// The pointer is not automatically managed by TinyGo hence it must be freed by the host.
func StringToLeakedPtr(s string) (uint32, uint32) {
size := C.ulong(len(s))
ptr := unsafe.Pointer(C.malloc(size))
copy(unsafe.Slice((*byte)(ptr), size), s)
return uint32(uintptr(ptr)), uint32(size)
}