| // 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 |
| } |