[cap-talk] SAML assertions as capabilities vs. ocaps

Kevin Reid kpreid at mac.com
Sat May 31 16:04:05 CDT 2008


Here's my (much delayed) second attempt. This version is designed to  
simulate the functioning of Alan Karp's SAML-cap system as he's  
described it, in an object-capability system, without introducing any  
additional messages between would-be-separated parties.

I haven't thoroughly tested or reviewed this; I would like to hear  
about any flaws you see in it.

Also, please do ask questions or point out parts which are unclear,  
so that I can rewrite or document them.

http://wiki.erights.org/wiki/User:Kevin_Reid/Offline_delegation


(The ::"foo" syntax is merely quoting for identifiers which are  
otherwise reserved keywords in the E syntax.)


# Copyright 2008 Kevin Reid, under the terms of the MIT X license
# found at http://www.opensource.org/licenses/mit- 
license.html ................

pragma.syntax("0.9")

# --- Utilities ---

def makeProxy := <elib:ref.makeProxy>
def makeBrand := <elib:sealing.makeBrand>

def everything {
   to contains(_) { return true }
}

# --- Signing ---

interface ::"Signed" guards SignedStamp {}

def makeSigner(label) {
   def who {
     to __printOn(out) {
       out.print("<", label, ">")
     }
   }
   def signer {
     to __printOn(out) {
       out.print("<signing as ", label, ">")
     }
     to who() { return who }
     to run(what) {
       def ::"signed" implements SignedStamp {
         to _who() { return who }
         to _get() { return what }
       }
       return ::"signed"
     }
   }
   return signer
}

def verifyAndGet(::"signed" : ::"Signed") {
   return [::"signed"._get(), ::"signed"._who()]
}

# --- Operations ---

def ::"delegate"(scap, filter, note) {
   def [cert, signer, host] := scap
   def newSigner := makeSigner(note)
   return [signer(["delegate", cert, newSigner.who(), filter]),  
newSigner, host]
}

/** Turn an object whose methods take an extra argument for the  
delegation chain into a scap. */
def exportOD(handler) {
   def rootSigner := makeSigner("export root")


   def handleMessage(delegators, verb :String, args :List, cert) {
     def [[=="delegate", prevCert, whoTo, filter], whoBy] :=  
verifyAndGet(cert)
     if (!filter.contains(verb)) {
       throw(`$verb not permitted by $whoBy`)
     }

     def delegators1 := delegators.with(whoTo)
     return if (whoBy != rootSigner.who()) {
       handleMessage(delegators1, verb, args, prevCert)
     } else {
       E.call(handler, verb, [delegators1] + args)
     }
   }

   def host(verb, args, cert) {
     handleMessage([], verb, args, cert)
   }

   return [rootSigner(["delegate", Ref.broken("n/a"), rootSigner.who 
(), everything]), rootSigner, host]
}

/** Turn a scap into a normal invokable reference. */
def importOD(scap) {
   def [cert, signer, host] := scap
   return makeProxy(def handler {
     to handleSend(verb, args) {
       return host <- (verb, args, cert)
     }
     to handleSendOnly(verb, args) {
       return host <- (verb, args, cert)
     }
     to handleOptSealedDispatch(_) {}
   }, Ref.whenBroken(host, fn _ {Ref.optProblem(host)}), true)
}

# --- Example ---

def carol(x) {
   def xr := importOD(x)
   xr <- hello("world")
}

def bob(x) {
   def xr := importOD(x)
   when ( carol <- (::"delegate"(x, ["hello"].asSet(), "Carol")) ) -> {
     xr <- goodbye()
   }
}

def alice(x) {
   bob <- (::"delegate"(x, ["hello", "goodbye"].asSet(), "Bob"))
}

def root := exportOD(def root0 {
   to hello(chain, greeted) {
     println(chain, " greeted ", greeted)
   }
   to goodbye(chain) {
     println(chain, " said goodbye")
   }
})
alice(::"delegate"(root, ["hello", "goodbye"].asSet(), "Alice"))

-- 
Kevin Reid                            <http://homepage.mac.com/kpreid/>




More information about the cap-talk mailing list