blob: 04334f5714fb7cac32a89ef16fce99afc1380dd2 [file] [log] [blame]
Srdjan Petrovic7602c272014-08-21 13:56:28 -07001// +build android
2
Srdjan Petrovice2f5fce2014-08-21 15:07:24 -07003package security
Srdjan Petrovic7602c272014-08-21 13:56:28 -07004
5import (
6 "runtime"
7 "unsafe"
8
Srdjan Petrovice2f5fce2014-08-21 15:07:24 -07009 "veyron/jni/runtimes/google/util"
Srdjan Petrovic7602c272014-08-21 13:56:28 -070010 "veyron2/security"
11)
12
13// #cgo LDFLAGS: -ljniwrapper
14// #include "jni_wrapper.h"
15import "C"
16
17// NewPublicIDStore creates an instance of security.PublicIDStore that uses the
18// provided Java PublicIDStore as its underlying implementation.
19// NOTE: Because CGO creates package-local types and because this method may be
20// invoked from a different package, Java types are passed in an empty interface
21// and then cast into their package local types.
22func NewPublicIDStore(jEnv, jStore interface{}) security.PublicIDStore {
23 env := (*C.JNIEnv)(unsafe.Pointer(util.PtrValue(jEnv)))
24 jPublicIDStore := C.jobject(unsafe.Pointer(util.PtrValue(jStore)))
25
26 // We cannot cache Java environments as they are only valid in the current
27 // thread. We can, however, cache the Java VM and obtain an environment
28 // from it in whatever thread happens to be running at the time.
29 var jVM *C.JavaVM
30 if status := C.GetJavaVM(env, &jVM); status != 0 {
31 panic("couldn't get Java VM from the (Java) environment")
32 }
33
34 // Reference Java PublicIDStore; it will be de-referenced when the Go
35 // PublicIDStore created below is garbage-collected (through the finalizer
36 // callback we setup just below).
37 jPublicIDStore = C.NewGlobalRef(env, jPublicIDStore)
38 // Create Go PublicIDStore.
39 s := &publicIDStore{
40 jVM: jVM,
41 jPublicIDStore: jPublicIDStore,
42 }
43 runtime.SetFinalizer(s, func(s *publicIDStore) {
44 envPtr, freeFunc := util.GetEnv(s.jVM)
45 env := (*C.JNIEnv)(envPtr)
46 defer freeFunc()
47 C.DeleteGlobalRef(env, s.jPublicIDStore)
48 })
49 return s
50}
51
52type publicIDStore struct {
53 jVM *C.JavaVM
54 jPublicIDStore C.jobject
55}
56
Asim Shankar6bc64582014-08-27 12:51:42 -070057func (s *publicIDStore) Add(id security.PublicID, peerPattern security.BlessingPattern) error {
Srdjan Petrovic7602c272014-08-21 13:56:28 -070058 envPtr, freeFunc := util.GetEnv(s.jVM)
59 env := (*C.JNIEnv)(envPtr)
60 defer freeFunc()
61 util.GoRef(&id) // Un-refed when the Java PublicID object created below is finalized.
62 jPublicID := C.jobject(util.NewObjectOrCatch(env, jPublicIDImplClass, []util.Sign{util.LongSign}, &id))
Asim Shankar6bc64582014-08-27 12:51:42 -070063 jBlessingPattern := C.jobject(util.NewObjectOrCatch(env, jBlessingPatternClass, []util.Sign{util.StringSign}, string(peerPattern)))
64 return util.CallVoidMethod(env, s.jPublicIDStore, "add", []util.Sign{publicIDSign, principalPatternSign}, jPublicID, jBlessingPattern)
Srdjan Petrovic7602c272014-08-21 13:56:28 -070065}
66
67func (s *publicIDStore) ForPeer(peer security.PublicID) (security.PublicID, error) {
68 envPtr, freeFunc := util.GetEnv(s.jVM)
69 env := (*C.JNIEnv)(envPtr)
70 defer freeFunc()
71 util.GoRef(&peer) // Un-refed when the Java peer object created below is finalized.
72 jPeer := C.jobject(util.NewObjectOrCatch(env, jPublicIDImplClass, []util.Sign{util.LongSign}, &peer))
73 jPublicID, err := util.CallObjectMethod(env, s.jPublicIDStore, "forPeer", []util.Sign{publicIDSign}, publicIDSign, jPeer)
74 if err != nil {
75 return nil, err
76 }
77 publicIDPtr := util.CallLongMethodOrCatch(env, jPublicID, "getNativePtr", nil)
78 return (*(*security.PublicID)(util.Ptr(publicIDPtr))), nil
79}
80
81func (s *publicIDStore) DefaultPublicID() (security.PublicID, error) {
82 envPtr, freeFunc := util.GetEnv(s.jVM)
83 env := (*C.JNIEnv)(envPtr)
84 defer freeFunc()
85 jPublicID, err := util.CallObjectMethod(env, s.jPublicIDStore, "defaultPublicID", []util.Sign{}, publicIDSign)
86 if err != nil {
87 return nil, err
88 }
89 publicIDPtr := util.CallLongMethodOrCatch(env, jPublicID, "getNativePtr", nil)
90 return (*(*security.PublicID)(util.Ptr(publicIDPtr))), nil
91}
92
Asim Shankar6bc64582014-08-27 12:51:42 -070093func (s *publicIDStore) SetDefaultBlessingPattern(pattern security.BlessingPattern) error {
Srdjan Petrovic7602c272014-08-21 13:56:28 -070094 envPtr, freeFunc := util.GetEnv(s.jVM)
95 env := (*C.JNIEnv)(envPtr)
96 defer freeFunc()
Asim Shankar6bc64582014-08-27 12:51:42 -070097 jPattern := C.jobject(util.NewObjectOrCatch(env, jBlessingPatternClass, []util.Sign{util.StringSign}, string(pattern)))
98 return util.CallVoidMethod(env, s.jPublicIDStore, "setDefaultBlessingPattern", []util.Sign{principalPatternSign}, jPattern)
Srdjan Petrovic7602c272014-08-21 13:56:28 -070099}