Rearranged wasm challenge utils
This commit is contained in:
118
lib/challenge/wasm/interface/interface.go
Normal file
118
lib/challenge/wasm/interface/interface.go
Normal 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
|
||||
)
|
||||
10
lib/challenge/wasm/interface/interface_generic.go
Normal file
10
lib/challenge/wasm/interface/interface_generic.go
Normal 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") }
|
||||
59
lib/challenge/wasm/interface/interface_tinygo.go
Normal file
59
lib/challenge/wasm/interface/interface_tinygo.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user