Srdjan Petrovic | 7602c27 | 2014-08-21 13:56:28 -0700 | [diff] [blame] | 1 | // +build android |
| 2 | |
Srdjan Petrovic | e2f5fce | 2014-08-21 15:07:24 -0700 | [diff] [blame] | 3 | package security |
Srdjan Petrovic | 7602c27 | 2014-08-21 13:56:28 -0700 | [diff] [blame] | 4 | |
| 5 | import ( |
| 6 | "runtime" |
| 7 | "unsafe" |
| 8 | |
Srdjan Petrovic | e2f5fce | 2014-08-21 15:07:24 -0700 | [diff] [blame] | 9 | "veyron/jni/runtimes/google/util" |
Srdjan Petrovic | 7602c27 | 2014-08-21 13:56:28 -0700 | [diff] [blame] | 10 | "veyron2/security" |
| 11 | ) |
| 12 | |
| 13 | // #cgo LDFLAGS: -ljniwrapper |
| 14 | // #include "jni_wrapper.h" |
| 15 | import "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. |
| 22 | func 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 | |
| 52 | type publicIDStore struct { |
| 53 | jVM *C.JavaVM |
| 54 | jPublicIDStore C.jobject |
| 55 | } |
| 56 | |
Asim Shankar | 6bc6458 | 2014-08-27 12:51:42 -0700 | [diff] [blame^] | 57 | func (s *publicIDStore) Add(id security.PublicID, peerPattern security.BlessingPattern) error { |
Srdjan Petrovic | 7602c27 | 2014-08-21 13:56:28 -0700 | [diff] [blame] | 58 | 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 Shankar | 6bc6458 | 2014-08-27 12:51:42 -0700 | [diff] [blame^] | 63 | 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 Petrovic | 7602c27 | 2014-08-21 13:56:28 -0700 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | func (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 | |
| 81 | func (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 Shankar | 6bc6458 | 2014-08-27 12:51:42 -0700 | [diff] [blame^] | 93 | func (s *publicIDStore) SetDefaultBlessingPattern(pattern security.BlessingPattern) error { |
Srdjan Petrovic | 7602c27 | 2014-08-21 13:56:28 -0700 | [diff] [blame] | 94 | envPtr, freeFunc := util.GetEnv(s.jVM) |
| 95 | env := (*C.JNIEnv)(envPtr) |
| 96 | defer freeFunc() |
Asim Shankar | 6bc6458 | 2014-08-27 12:51:42 -0700 | [diff] [blame^] | 97 | 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 Petrovic | 7602c27 | 2014-08-21 13:56:28 -0700 | [diff] [blame] | 99 | } |