storj/lib/uplinkc/project.go
Jeff Wendling a35eb8027e lib/uplinkc: do some checks around conversions and allocations
ensure that every integer conversion fits into the destination
type, and for any unchecked ones, annotate why they are safe.
additionally, any integers we pass into slice headers need to
check that they are not negative.

all of our allocations should check for allocation failure and
return an error if there was a problem. even though an allocation
just failed, we don't pre-allocate the failure because we don't
want the callers to free it like they have to with the other
errors we return. maybe we should just panic.

Change-Id: Id4dfad802d312d35e565041efc9872453c90d793
2020-01-01 17:36:34 +00:00

90 lines
2.2 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package main
// #include "uplink_definitions.h"
import "C"
import (
"fmt"
"storj.io/common/storj"
libuplink "storj.io/storj/lib/uplink"
)
// Project is a scoped uplink.Project
type Project struct {
scope
*libuplink.Project
}
//export open_project
// open_project opens project using uplink
func open_project(uplinkHandle C.UplinkRef, satelliteAddr *C.char, apikeyHandle C.APIKeyRef, cerr **C.char) C.ProjectRef {
uplink, ok := universe.Get(uplinkHandle._handle).(*Uplink)
if !ok {
*cerr = C.CString("invalid uplink")
return C.ProjectRef{}
}
apikey, ok := universe.Get(apikeyHandle._handle).(libuplink.APIKey)
if !ok {
*cerr = C.CString("invalid apikey")
return C.ProjectRef{}
}
scope := uplink.scope.child()
project, err := uplink.OpenProject(scope.ctx, C.GoString(satelliteAddr), apikey)
if err != nil {
*cerr = C.CString(fmt.Sprintf("%+v", err))
return C.ProjectRef{}
}
return C.ProjectRef{universe.Add(&Project{scope, project})}
}
//export project_salted_key_from_passphrase
// project_salted_key_from_passphrase returns a key generated from the given passphrase
// using a stable, project-specific salt
func project_salted_key_from_passphrase(projectHandle C.ProjectRef, passphrase *C.char, cerr **C.char) *C.uint8_t {
project, ok := universe.Get(projectHandle._handle).(*Project)
if !ok {
*cerr = C.CString("invalid project")
return nil
}
saltedKey, err := project.SaltedKeyFromPassphrase(project.ctx, C.GoString(passphrase))
if err != nil {
*cerr = C.CString(fmt.Sprintf("%+v", err))
return nil
}
ptr := C.malloc(storj.KeySize)
if ptr == nil {
*cerr = C.CString("unable to allocate")
return nil
}
key := (*storj.Key)(ptr)
copy(key[:], saltedKey[:])
return (*C.uint8_t)(ptr)
}
//export close_project
// close_project closes the project.
func close_project(projectHandle C.ProjectRef, cerr **C.char) {
project, ok := universe.Get(projectHandle._handle).(*Project)
if !ok {
*cerr = C.CString("invalid project")
return
}
universe.Del(projectHandle._handle)
defer project.cancel()
if err := project.Close(); err != nil {
*cerr = C.CString(fmt.Sprintf("%+v", err))
return
}
}