blob: 712cb6df7d47519bf6b8e7c9d547f7d3d36696ba [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 (
"fmt"
"log"
"runtime"
"v.io/v23/security"
jutil "v.io/x/jni/util"
)
// #include "jni.h"
import "C"
// JavaPrincipal converts the provided Go Principal into a Java VPrincipal
// object.
func JavaPrincipal(env jutil.Env, principal security.Principal) (jutil.Object, error) {
if principal == nil {
return jutil.NullObject, nil
}
ref := jutil.GoNewRef(&principal) // Un-refed when the Java VPrincipalImpl is finalized.
jPrincipal, err := jutil.NewObject(env, jVPrincipalImplClass, []jutil.Sign{jutil.LongSign, signerSign, blessingStoreSign, blessingRootsSign}, int64(ref), jutil.NullObject, jutil.NullObject, jutil.NullObject)
if err != nil {
jutil.GoDecRef(ref)
return jutil.NullObject, err
}
return jPrincipal, nil
}
// GoPrincipal converts the provided Java VPrincipal object into a Go Principal.
func GoPrincipal(env jutil.Env, jPrincipal jutil.Object) (security.Principal, error) {
if jPrincipal.IsNull() {
return nil, nil
}
if jutil.IsInstanceOf(env, jPrincipal, jVPrincipalImplClass) {
// Called with our implementation of VPrincipal, which maintains a Go reference - use it.
ref, err := jutil.CallLongMethod(env, jPrincipal, "nativeRef", nil)
if err != nil {
return nil, err
}
return (*(*security.Principal)(jutil.GoRefValue(jutil.Ref(ref)))), nil
}
// Reference Java VPrincipal; it will be de-referenced when the Go Principal
// created below is garbage-collected (through the finalizer callback we
// setup just below).
jPrincipal = jutil.NewGlobalRef(env, jPrincipal)
// Create Go Principal.
p := &principal{
jPrincipal: jPrincipal,
}
runtime.SetFinalizer(p, func(p *principal) {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jutil.DeleteGlobalRef(env, p.jPrincipal)
})
return p, nil
}
type principal struct {
jPrincipal jutil.Object
}
func (p *principal) Bless(key security.PublicKey, with security.Blessings, extension string, caveat security.Caveat, additionalCaveats ...security.Caveat) (security.Blessings, error) {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jKey, err := JavaPublicKey(env, key)
if err != nil {
return security.Blessings{}, err
}
jWith, err := JavaBlessings(env, with)
if err != nil {
return security.Blessings{}, err
}
jCaveat, err := JavaCaveat(env, caveat)
if err != nil {
return security.Blessings{}, err
}
jAdditionalCaveats, err := JavaCaveatArray(env, additionalCaveats)
if err != nil {
return security.Blessings{}, err
}
jBlessings, err := jutil.CallObjectMethod(env, p.jPrincipal, "bless", []jutil.Sign{publicKeySign, blessingsSign, jutil.StringSign, caveatSign, jutil.ArraySign(caveatSign)}, blessingsSign, jKey, jWith, extension, jCaveat, jAdditionalCaveats)
if err != nil {
return security.Blessings{}, err
}
return GoBlessings(env, jBlessings)
}
func (p *principal) BlessSelf(name string, caveats ...security.Caveat) (security.Blessings, error) {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jCaveats, err := JavaCaveatArray(env, caveats)
if err != nil {
return security.Blessings{}, err
}
jBlessings, err := jutil.CallObjectMethod(env, p.jPrincipal, "blessSelf", []jutil.Sign{jutil.StringSign, jutil.ArraySign(caveatSign)}, blessingsSign, name, jCaveats)
if err != nil {
return security.Blessings{}, err
}
return GoBlessings(env, jBlessings)
}
func (p *principal) Sign(message []byte) (security.Signature, error) {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jSig, err := jutil.CallObjectMethod(env, p.jPrincipal, "sign", []jutil.Sign{jutil.ArraySign(jutil.ByteSign)}, signatureSign, message)
if err != nil {
return security.Signature{}, err
}
return GoSignature(env, jSig)
}
func (p *principal) MintDischarge(forThirdPartyCaveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge ...security.Caveat) (security.Discharge, error) {
return security.Discharge{}, fmt.Errorf("MintDischarge not yet implemented")
}
func (p *principal) PublicKey() security.PublicKey {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jPublicKey, err := jutil.CallObjectMethod(env, p.jPrincipal, "publicKey", nil, publicKeySign)
if err != nil {
log.Printf("Couldn't get Java public key: %v", err)
return nil
}
key, err := GoPublicKey(env, jPublicKey)
if err != nil {
log.Printf("Couldn't convert Java public key to Go: %v", err)
return nil
}
return key
}
func (p *principal) BlessingStore() security.BlessingStore {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jBlessingStore, err := jutil.CallObjectMethod(env, p.jPrincipal, "blessingStore", nil, blessingStoreSign)
if err != nil {
log.Printf("Couldn't get Java Blessing Store: %v", err)
return nil
}
store, err := GoBlessingStore(env, jBlessingStore)
if err != nil {
log.Printf("Couldn't convert Java Blessing Store to Go: %v", err)
return nil
}
return store
}
func (p *principal) Roots() security.BlessingRoots {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jBlessingRoots, err := jutil.CallObjectMethod(env, p.jPrincipal, "roots", nil, blessingRootsSign)
if err != nil {
log.Printf("Couldn't get Java Blessing Roots: %v", err)
return nil
}
roots, err := GoBlessingRoots(env, jBlessingRoots)
if err != nil {
log.Printf("Couldn't convert Java Blessing Roots to Go: %v", err)
return nil
}
return roots
}