blob: 8f33278d1d5aeda1a1d6fb74632a6f0dd5559c38 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build java android
package security
import (
"log"
"runtime"
"unsafe"
"v.io/v23/security"
jutil "v.io/x/jni/util"
)
// #include "jni.h"
import "C"
// JavaBlessingRoots creates an instance of Java BlessingRoots that uses the provided Go
// BlessingRoots as its underlying implementation.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func JavaBlessingRoots(jEnv interface{}, roots security.BlessingRoots) (unsafe.Pointer, error) {
jObj, err := jutil.NewObject(jEnv, jBlessingRootsImplClass, []jutil.Sign{jutil.LongSign}, int64(jutil.PtrValue(&roots)))
if err != nil {
return nil, err
}
jutil.GoRef(&roots) // Un-refed when the Java BlessingRootsImpl is finalized.
return jObj, nil
}
// GoBlessingRoots creates an instance of security.BlessingRoots that uses the
// provided Java BlessingRoots as its underlying implementation.
// NOTE: Because CGO creates package-local types and because this method may be
// invoked from a different package, Java types are passed in an empty interface
// and then cast into their package local types.
func GoBlessingRoots(jEnv, jBlessingRootsObj interface{}) (security.BlessingRoots, error) {
if jBlessingRootsObj == nil {
return nil, nil
}
// Reference Java BlessingRoots; it will be de-referenced when the Go
// BlessingRoots created below is garbage-collected (through the finalizer
// callback we setup just below).
jBlessingRoots := C.jobject(jutil.NewGlobalRef(jEnv, jBlessingRootsObj))
r := &blessingRoots{
jBlessingRoots: jBlessingRoots,
}
runtime.SetFinalizer(r, func(r *blessingRoots) {
envPtr, freeFunc := jutil.GetEnv()
env := (*C.JNIEnv)(envPtr)
defer freeFunc()
jutil.DeleteGlobalRef(env, r.jBlessingRoots)
})
return r, nil
}
type blessingRoots struct {
jBlessingRoots C.jobject
}
func (r *blessingRoots) Add(root security.PublicKey, pattern security.BlessingPattern) error {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jRoot, err := JavaPublicKey(env, root)
if err != nil {
return err
}
jPattern, err := JavaBlessingPattern(env, pattern)
if err != nil {
return err
}
return jutil.CallVoidMethod(env, r.jBlessingRoots, "add", []jutil.Sign{publicKeySign, blessingPatternSign}, jRoot, jPattern)
}
func (r *blessingRoots) Recognized(root security.PublicKey, blessing string) error {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jRoot, err := JavaPublicKey(env, root)
if err != nil {
return err
}
return jutil.CallVoidMethod(env, r.jBlessingRoots, "recognized", []jutil.Sign{publicKeySign, jutil.StringSign}, jRoot, blessing)
}
func (r *blessingRoots) DebugString() string {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
ret, err := jutil.CallStringMethod(env, r.jBlessingRoots, "debugString", nil)
if err != nil {
log.Printf("Couldn't get Java DebugString: %v", err)
return ""
}
return ret
}
func (r *blessingRoots) Dump() map[security.BlessingPattern][]security.PublicKey {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
ret, err := jutil.CallMultimapMethod(env, r.jBlessingRoots, "dump", []jutil.Sign{})
if err != nil {
log.Printf("Couldn't get Java Dump: %v", err)
return nil
}
result := make(map[security.BlessingPattern][]security.PublicKey)
for jPattern, jKeys := range ret {
pattern, err := GoBlessingPattern(env, jPattern)
if err != nil {
log.Printf("Couldn't convert Java BlessingPattern: %v", err)
return nil
}
var entry []security.PublicKey
for _, jKey := range jKeys {
key, err := GoPublicKey(env, jKey)
if err != nil {
log.Printf("Couldn't convert Java PublicKey: %v", err)
return nil
}
entry = append(entry, key)
}
result[pattern] = entry
}
return result
}