veyron/runtimes/google/security/jni: added Java PublicIDStore interface.
Change-Id: I7a9916ed4fea8b54ce5744848dab3f9587a20aed
diff --git a/runtimes/google/ipc/jni/jni.go b/runtimes/google/ipc/jni/jni.go
index d9115f1..625f73c 100644
--- a/runtimes/google/ipc/jni/jni.go
+++ b/runtimes/google/ipc/jni/jni.go
@@ -79,6 +79,13 @@
id := jnisecurity.NewPrivateID(env, jPrivateID)
ret = append(ret, veyron2.RuntimeID(id))
}
+ // Process RuntimePublicIDStoreOpt
+ runtimePublicIDStoreKey := util.JStaticStringField(env, jOptionDefsClass, "RUNTIME_PUBLIC_ID_STORE")
+ if util.CallBooleanMethodOrCatch(env, jOptions, "has", []util.Sign{util.StringSign}, runtimePublicIDStoreKey) {
+ jStore := C.jobject(util.CallObjectMethodOrCatch(env, jOptions, "get", []util.Sign{util.StringSign}, util.ObjectSign, runtimePublicIDStoreKey))
+ store := jnisecurity.NewPublicIDStore(env, jStore)
+ ret = append(ret, veyron2.RuntimePublicIDStore(store))
+ }
return
}
diff --git a/runtimes/google/jni/util/util.go b/runtimes/google/jni/util/util.go
index 13ad34b..284f620 100644
--- a/runtimes/google/jni/util/util.go
+++ b/runtimes/google/jni/util/util.go
@@ -198,6 +198,17 @@
return errors.New(GoString(env, jMsg))
}
+// JObjectFieldPtr returns the value of the provided Java object's Object field.
+// 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 JObjectFieldPtr(jEnv, jObj interface{}, field string) unsafe.Pointer {
+ env := getEnv(jEnv)
+ obj := getObject(jObj)
+ fid := C.jfieldID(JFieldIDPtrOrDie(env, C.GetObjectClass(env, obj), field, ObjectSign))
+ return unsafe.Pointer(C.GetObjectField(env, obj, fid))
+}
+
// JBoolField returns the value of the provided Java object's boolean field.
// 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
diff --git a/runtimes/google/security/jni/jni.go b/runtimes/google/security/jni/jni.go
index a89744a..499f2dd 100644
--- a/runtimes/google/security/jni/jni.go
+++ b/runtimes/google/security/jni/jni.go
@@ -31,6 +31,11 @@
jPrincipalPatternClass C.jclass
// Global reference for org.joda.time.Duration class.
jDurationClass C.jclass
+
+ // Signature of the PublicID interface.
+ publicIDSign = util.ClassSign("com.veyron2.security.PublicID")
+ // Signature of the PrincipalPattern class.
+ principalPatternSign = util.ClassSign("com.veyron2.security.PrincipalPattern")
)
// Init initializes the JNI code with the given Java evironment. This method
@@ -52,6 +57,76 @@
jDurationClass = C.jclass(util.JFindClassPtrOrDie(env, "org/joda/time/Duration"))
}
+//export Java_com_veyron_runtimes_google_security_PublicIDStore_nativeCreate
+func Java_com_veyron_runtimes_google_security_PublicIDStore_nativeCreate(env *C.JNIEnv, jPublicIDStoreClass C.jclass, jParams C.jobject) C.jlong {
+ var params *isecurity.PublicIDStoreParams
+ if jParams != nil {
+ dir := util.JStringField(env, jParams, "dir")
+ jSigner := C.jobject(util.JObjectFieldPtr(env, jParams, "signer"))
+ signer := newSigner(env, jSigner)
+ params = &isecurity.PublicIDStoreParams{
+ Dir: dir,
+ Signer: signer,
+ }
+ }
+ store, err := isecurity.NewPublicIDStore(params)
+ if err != nil {
+ util.JThrowV(env, err)
+ return C.jlong(0)
+ }
+ util.GoRef(&store) // Un-refed when the Java PublicIDStore is finalized.
+ return C.jlong(util.PtrValue(&store))
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicIDStore_nativeAdd
+func Java_com_veyron_runtimes_google_security_PublicIDStore_nativeAdd(env *C.JNIEnv, jPublicIDStore C.jobject, goPublicIDStorePtr C.jlong, jID C.jobject, jPeerPattern C.jstring) {
+ idPtr := util.CallLongMethodOrCatch(env, jID, "getNativePtr", nil)
+ id := (*(*security.PublicID)(util.Ptr(idPtr)))
+ peerPattern := security.PrincipalPattern(util.GoString(env, jPeerPattern))
+ if err := (*(*security.PublicIDStore)(util.Ptr(goPublicIDStorePtr))).Add(id, peerPattern); err != nil {
+ util.JThrowV(env, err)
+ return
+ }
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicIDStore_nativeGetPeerID
+func Java_com_veyron_runtimes_google_security_PublicIDStore_nativeGetPeerID(env *C.JNIEnv, jPublicIDStore C.jobject, goPublicIDStorePtr C.jlong, jPeerID C.jobject) C.jlong {
+ peerIDPtr := util.CallLongMethodOrCatch(env, jPeerID, "getNativePtr", nil)
+ peerID := (*(*security.PublicID)(util.Ptr(peerIDPtr)))
+ id, err := (*(*security.PublicIDStore)(util.Ptr(goPublicIDStorePtr))).ForPeer(peerID)
+ if err != nil {
+ util.JThrowV(env, err)
+ return C.jlong(0)
+ }
+ util.GoRef(&id) // Un-refed when the Java PublicID is finalized.
+ return C.jlong(util.PtrValue(&id))
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicIDStore_nativeDefaultPublicID
+func Java_com_veyron_runtimes_google_security_PublicIDStore_nativeDefaultPublicID(env *C.JNIEnv, jPublicIDStore C.jobject, goPublicIDStorePtr C.jlong) C.jlong {
+ id, err := (*(*security.PublicIDStore)(util.Ptr(goPublicIDStorePtr))).DefaultPublicID()
+ if err != nil {
+ util.JThrowV(env, err)
+ return C.jlong(0)
+ }
+ util.GoRef(&id) // Un-refed when the Java PublicID is finalized.
+ return C.jlong(util.PtrValue(&id))
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicIDStore_nativeSetDefaultPrincipalPattern
+func Java_com_veyron_runtimes_google_security_PublicIDStore_nativeSetDefaultPrincipalPattern(env *C.JNIEnv, jPublicIDStore C.jobject, goPublicIDStorePtr C.jlong, jPattern C.jstring) {
+ pattern := security.PrincipalPattern(util.GoString(env, jPattern))
+ if err := (*(*security.PublicIDStore)(util.Ptr(goPublicIDStorePtr))).SetDefaultPrincipalPattern(pattern); err != nil {
+ util.JThrowV(env, err)
+ return
+ }
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicIDStore_nativeFinalize
+func Java_com_veyron_runtimes_google_security_PublicIDStore_nativeFinalize(env *C.JNIEnv, jPublicIDStore C.jobject, goPublicIDStorePtr C.jlong) {
+ util.GoUnref((*security.PublicIDStore)(util.Ptr(goPublicIDStorePtr)))
+}
+
//export Java_com_veyron_runtimes_google_security_PublicID_nativeNames
func Java_com_veyron_runtimes_google_security_PublicID_nativeNames(env *C.JNIEnv, jPublicID C.jobject, goPublicIDPtr C.jlong) C.jobjectArray {
names := (*(*security.PublicID)(util.Ptr(goPublicIDPtr))).Names()
diff --git a/runtimes/google/security/jni/privateid.go b/runtimes/google/security/jni/privateid.go
index 71fb68b..b223a34 100644
--- a/runtimes/google/security/jni/privateid.go
+++ b/runtimes/google/security/jni/privateid.go
@@ -16,10 +16,6 @@
// #include "jni_wrapper.h"
import "C"
-var (
- publicIDSign = util.ClassSign("com.veyron2.security.PublicID")
-)
-
// NewPrivateID creates an instance of security.PrivateID that uses the provided
// Java PrivateID as its underlying implementation.
// NOTE: Because CGO creates package-local types and because this method may be
diff --git a/runtimes/google/security/jni/publicid_store.go b/runtimes/google/security/jni/publicid_store.go
new file mode 100644
index 0000000..eeb0e3a
--- /dev/null
+++ b/runtimes/google/security/jni/publicid_store.go
@@ -0,0 +1,99 @@
+// +build android
+
+package jni
+
+import (
+ "runtime"
+ "unsafe"
+
+ "veyron/runtimes/google/jni/util"
+ "veyron2/security"
+)
+
+// #cgo LDFLAGS: -ljniwrapper
+// #include "jni_wrapper.h"
+import "C"
+
+// NewPublicIDStore creates an instance of security.PublicIDStore that uses the
+// provided Java PublicIDStore 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 NewPublicIDStore(jEnv, jStore interface{}) security.PublicIDStore {
+ env := (*C.JNIEnv)(unsafe.Pointer(util.PtrValue(jEnv)))
+ jPublicIDStore := C.jobject(unsafe.Pointer(util.PtrValue(jStore)))
+
+ // We cannot cache Java environments as they are only valid in the current
+ // thread. We can, however, cache the Java VM and obtain an environment
+ // from it in whatever thread happens to be running at the time.
+ var jVM *C.JavaVM
+ if status := C.GetJavaVM(env, &jVM); status != 0 {
+ panic("couldn't get Java VM from the (Java) environment")
+ }
+
+ // Reference Java PublicIDStore; it will be de-referenced when the Go
+ // PublicIDStore created below is garbage-collected (through the finalizer
+ // callback we setup just below).
+ jPublicIDStore = C.NewGlobalRef(env, jPublicIDStore)
+ // Create Go PublicIDStore.
+ s := &publicIDStore{
+ jVM: jVM,
+ jPublicIDStore: jPublicIDStore,
+ }
+ runtime.SetFinalizer(s, func(s *publicIDStore) {
+ envPtr, freeFunc := util.GetEnv(s.jVM)
+ env := (*C.JNIEnv)(envPtr)
+ defer freeFunc()
+ C.DeleteGlobalRef(env, s.jPublicIDStore)
+ })
+ return s
+}
+
+type publicIDStore struct {
+ jVM *C.JavaVM
+ jPublicIDStore C.jobject
+}
+
+func (s *publicIDStore) Add(id security.PublicID, peerPattern security.PrincipalPattern) error {
+ envPtr, freeFunc := util.GetEnv(s.jVM)
+ env := (*C.JNIEnv)(envPtr)
+ defer freeFunc()
+ util.GoRef(&id) // Un-refed when the Java PublicID object created below is finalized.
+ jPublicID := C.jobject(util.NewObjectOrCatch(env, jPublicIDImplClass, []util.Sign{util.LongSign}, &id))
+ jPrincipalPattern := C.jobject(util.NewObjectOrCatch(env, jPrincipalPatternClass, []util.Sign{util.StringSign}, string(peerPattern)))
+ return util.CallVoidMethod(env, s.jPublicIDStore, "add", []util.Sign{publicIDSign, principalPatternSign}, jPublicID, jPrincipalPattern)
+}
+
+func (s *publicIDStore) ForPeer(peer security.PublicID) (security.PublicID, error) {
+ envPtr, freeFunc := util.GetEnv(s.jVM)
+ env := (*C.JNIEnv)(envPtr)
+ defer freeFunc()
+ util.GoRef(&peer) // Un-refed when the Java peer object created below is finalized.
+ jPeer := C.jobject(util.NewObjectOrCatch(env, jPublicIDImplClass, []util.Sign{util.LongSign}, &peer))
+ jPublicID, err := util.CallObjectMethod(env, s.jPublicIDStore, "forPeer", []util.Sign{publicIDSign}, publicIDSign, jPeer)
+ if err != nil {
+ return nil, err
+ }
+ publicIDPtr := util.CallLongMethodOrCatch(env, jPublicID, "getNativePtr", nil)
+ return (*(*security.PublicID)(util.Ptr(publicIDPtr))), nil
+}
+
+func (s *publicIDStore) DefaultPublicID() (security.PublicID, error) {
+ envPtr, freeFunc := util.GetEnv(s.jVM)
+ env := (*C.JNIEnv)(envPtr)
+ defer freeFunc()
+ jPublicID, err := util.CallObjectMethod(env, s.jPublicIDStore, "defaultPublicID", []util.Sign{}, publicIDSign)
+ if err != nil {
+ return nil, err
+ }
+ publicIDPtr := util.CallLongMethodOrCatch(env, jPublicID, "getNativePtr", nil)
+ return (*(*security.PublicID)(util.Ptr(publicIDPtr))), nil
+}
+
+func (s *publicIDStore) SetDefaultPrincipalPattern(pattern security.PrincipalPattern) error {
+ envPtr, freeFunc := util.GetEnv(s.jVM)
+ env := (*C.JNIEnv)(envPtr)
+ defer freeFunc()
+ jPattern := C.jobject(util.NewObjectOrCatch(env, jPrincipalPatternClass, []util.Sign{util.StringSign}, string(pattern)))
+ return util.CallVoidMethod(env, s.jPublicIDStore, "setDefaultPrincipalPattern", []util.Sign{principalPatternSign}, jPattern)
+}