Cleaned up document and changed key discovery examples
author"arangana <arun@mozilla.com>"
Mon, 15 Jul 2013 13:46:45 -0400
changeset 37 5765a3364579
parent 36 02b1cd05d07d
child 38 ea834a664a86
Cleaned up document and changed key discovery examples
Overview.html
--- a/Overview.html	Fri Jul 12 16:36:21 2013 -0400
+++ b/Overview.html	Mon Jul 15 13:46:45 2013 -0400
@@ -77,17 +77,17 @@
       <p>Certain popular use cases for cryptography on the web do not correspond to the combined capabilities of the Key Discovery API [[webcrypto-key-discovery]] or the Web Cryptography API [[WebCryptoAPI]], and these use cases are not addressed here.  These include:
       </p>
       <ol>
-        <li><p>Any use case requiring a relaxation or violation of the same-origin policy in JavaScript, implemented by all the major web browsers.  This includes use cases that require direct access to cryptographic material that is not domain-specific from a key store that is not domain specific.  Currently, certain banking transactions require citizens to obtain certificates that are centrally issued, and that are user specific yet not domain specific, and that are used by multiple institutions, each having separate domains, each of which can call upon a hardware-based cryptographic material store.  Such use cases aren't directly addressed by the combination of the Web Cryptography API [[WebCryptoAPI]] or the Key Discovery API [[webcrypto-key-discovery]].  Instead, use cases that require cryptographic material to be shared between domains can leverage cross-origin messaging and the structured clonability of keys, or the importing and exporting of cryptographic keys across domains; such use cases are covered in this document.  Another use case not addressed here for the same reason is the case of a centrally issued electronic identity (eID) that exposes a certificate chain to web applications for use with digital signatures.</p> </li>
+        <li><p>Any use case requiring a relaxation or violation of the same-origin policy in JavaScript, implemented by all the major web browsers [[HTML]].  This includes use cases that require direct access to cryptographic material that is not domain-specific from a key store that is not domain specific.  Currently, certain banking transactions require citizens to obtain certificates that are centrally issued, and that are user specific yet not domain specific, and that are used by multiple institutions, each having separate domains, each of which can call upon a hardware-based cryptographic material store.  Such use cases aren't directly addressed by the combination of the Web Cryptography API [[WebCryptoAPI]] or the Key Discovery API [[webcrypto-key-discovery]].  Instead, use cases that require cryptographic material to be shared between domains can leverage cross-origin messaging [[HTML]] and the structured clonability of key objects in JavaScript [[WebCryptoAPI]], or the importing and exporting of cryptographic keys across domains; such use cases <em>are</em> covered in this document.  Another use case not addressed here for the same reason is the case of a centrally issued electronic identity (eID) that exposes a certificate chain to web applications for use with digital signatures.</p> </li>
         <li><p>Any use case that expressly requires the use of auxiliary cryptographic hardware, including smart cards or USB dongles.  Other standardization activities may provide mechanisms for these technologies to interact with web applications, but such use cases fall beyond the scope of this document.  Examples of this type of use case include "advanced electronic signatures" which rely on certificates issued on secure hardware by certifying authorities, typically acting under the aegis of state governments.</p></li>
       </ol>
     </section>
     <section id='reqs'>
       <h2>Requirements Covered By Use Cases</h2>
-      <p>This section presents required features of a cryptographic API, particularly the features that this use cases document will rely on.  It is possible that there is more than one algorithm and more than one mechanism to accomplish each of these features.  The section presents code names for each of the features, which will be used alongside each scenario, illustrating which feature is used.</p>
+      <p>This section presents required features of a cryptographic API, particularly the features that this use cases document will rely on.  It is possible that there is more than one algorithm and more than one mechanism to accomplish each of these features.  The section presents code names for each of the features, which will be used alongside each scenario, illustrating which feature is used.  The term <dfn id="document">document</dfn> is used to refer to any data exchange format usable within HTML [[HTML]] web applications, which ranges from plain text to images and videos, inclusive of marked-up formats.</p>
     <ul>
       <li><p><dfn title="digest" id="digest">DIGEST</dfn>, the ability to perform a cryptographic hash, where an algorithm that takes an arbitrary block of data returns a fixed-size bit sequence, called the <dfn id="hash-value">hash value</dfn>, such that any change to the block of data changes the hash value.</p></li>
       <li><p><dfn title="mac" id="mac">MAC</dfn>, the ability to generate a <em>message authentication code</em>, using an algorithm, with <dfn id="hmac">HMAC</dfn> being a specific kind of message authentication code, with a specific algorithm.</p></li>
-      <li><p><dfn title="sign" id="sign">SIGN</dfn>, the ability to digitally sign a document with a private key, such that upon verification of the signature with the corresponding public key, the document's authenticity from the point of view of the signature can be determined.  The term document in this context can refer to any kind of data used with web applications.</p></li>
+      <li><p><dfn title="sign" id="sign">SIGN</dfn>, the ability to digitally sign a document with a private key, such that upon verification of the signature with the corresponding public key, the document's authenticity from the point of view of the signature can be determined.  </p></li>
       <li><p><dfn title="verify" id="verify">VERIFY</dfn>, the ability to verify a digitally signed document, as well as verify a MAC or HMAC.</p></li>
       <li><p><dfn title="encrypt" id="encrypt">ENCRYPT</dfn>, the ability to encode a document using an encryption algorithm.  <dfn id="encrypt-sym">ENCRYPT-SYM</dfn> is a specific type of encryption using symmetric cryptographic keys, and <dfn id="encrypt-assym">ENCRYPT-ASSYM</dfn> is a specific type of encryption using assymetric cryptographic keys, typically a public and private key pair.</p></li> 
       <li><p><dfn title="decrypt" id="decrypt">DECRYPT</dfn>, the ability to decrypt a digitally signed document.  <dfn id="decrypt-sym">DECRYPT-SYM</dfn> is a specific type of decryption using symmetric keys, and <dfn id="decrypt-assym">DECRYPT-ASSYM</dfn> is a specific type of decryption using assymetric keys, typically a public and private key pair.</p></li>
@@ -98,7 +98,7 @@
       <li><p><dfn title="keyex" id="keyex">KEYEX</dfn>, the ability for two entities to exchange key(s) without interception by a third party, with <dfn id="keyex-dh">KEYEX-DH</dfn> representing Diffie-Hellman key exchange, a common application of safe key exchange. </p>
       <div class="note">This feature doesn't imply that every aspect of key exchange is covered, since much of key exchange often includes a network component, which isn't covered by the API.  The <a title="derive">DERIVE</a> feature, coupled with an a network exchange of key data outside the scope of this API, may be all that is required.</div>
       </li>
-      <li><p><dfn title="keycall" id="keycall">KEYCALL</dfn>, the ability to access a particular key (or key pair) from within a web application's key storage, which is within the web application's origin only, and has been generated, derived, or imported by that web application.  Here, the key storage might be IndexedDB [[INDEXEDDB]] or <code>localStorage</code>.  This feature should be compared and contrasted with <a title="namedkey">NAMEDKEY</a>.</p></li>
+      <li><p><dfn title="keycall" id="keycall">KEYCALL</dfn>, the ability to access a particular key (or key pair) from within a web application's key storage, which is within the web application's origin only, and has been generated, derived, or imported by that web application.  Here, the key storage might be IndexedDB [[INDEXEDDB]] or <code>localStorage</code> [[webstorage]].  This feature should be compared and contrasted with <a title="namedkey">NAMEDKEY</a>.</p></li>
       <li><p><dfn title="sym" id="sym">-SYM</dfn>, an abbreviation for <em>symmetric key cryptographic operations</em>, used in this document as a suffix to other features to specifically clarify the feature being invoked by the web application.</p></li>
       <li><p><dfn title="assym" id="assym">-ASSYM</dfn>, an abbreviation for <em>assymetric key cryptographic operations</em>, typically involving a public and private key pair, used in this document as a suffix to other features to specifically clarify the feature being invoked by the web application.</p></li>
       <li><p><dfn title="random" id="random">RANDOM</dfn>, the ability to generate cryptographically secure random numbers.</p></li>
@@ -159,7 +159,7 @@
           1. Generate an ArrayBufferView of the overall message.
           2. Bit-manipulate this with the ArrayBufferView API to obtain the portion of bytes 
           constituting the signature as an ArrayBufferView, and the message as an ArrayBufferView.
-          This could be based on an understood JWT paradigm.
+          This could use JWT objects.
           3. Obtain the public key of GB from IndexedDB -- pubGBKeySign -- a step not shown here.
           4. Verify the signature.
           5. Upon verification, decrypt the message.  This message can be decrypted only by Jae-Sang, using his private key          
@@ -216,28 +216,34 @@
 </p>
 
 <p>[<a title="namedkey">NAMEDKEY</a> | <a title="verify">VERIFY</a> | <a title="unwrap">UNWRAP</a> | <a title="mac">MAC</a> | <a title="encrypt-sym">ENCRYPT-SYM</a> | <a title="decrypt-sym">DECRYPT-SYM</a> | <a title="sign">SIGN</a>]</p>
-<p>The Key Discovery API [[webcrypto-key-discovery]] describes the provides a mechanism for an application in JavaScript to detect the presence of a pre-provisioned key using the name of a disclosed identifier. </p>
+<p>The Key Discovery API [[webcrypto-key-discovery]] provides a mechanism for an application in JavaScript to detect the presence of a pre-provisioned key using the name of a disclosed identifier.  Unlike other examples presented here, this example presumes a key store that is not IndexedDB [[INDEXEDDB]] or <code>localStorage</code> [[webstorage]]. </p>
 <pre class="example highlight prettyprint">
-var keys = window.getKeysByName("VetFlxL33t_Device.p1a.b11");
-keys.onerror = function(e){
-  fail("This device is not authorized for Video Service Provider videos.");
-  }
-keys.oncomplete = function(e){
-  if(e.target.result.name == "VetFlxL33t_Device.p1a.b11"){
-  // Perform further crypto operations
-   ... 
-  }
+window.cryptoKeys.getKeysByName("VetFlxL33t_Device.p1a.b11").then(
+function authorize(namedKey)
+{
+  if(namedKey.name = "VetFlxL33t_Device.p1a.b11")
+  // Authorize
+  // else console.log.bind(console, "Device Not Authorized!")
 }
+function signUp()
+{
+  // Named Key not found scenario
+  // Convert new device to New User
+
+  .....
+}
+);
+
 </pre>
 
-<p>Ryan creates an account with the service provider and signs up for the lowest level of service, which enables him to connect five devices to the service at any one time. Ryan's account creation involved the creation of a specific key pair to uniquely identify him. [<a title="derive-asym">DERIVE-ASSYM</a> | <a title="keyex">KEYEX</a> | <a title="keycall">KEYCALL</a> | <a title="sign">SIGN</a> | <a title="verify">VERIFY</a>]</p>
+<p>Ryan creates an account with the service provider and signs up for the lowest level of service, which enables him to connect five devices to the service at any one time. Ryan's account creation involved the creation of a specific key pair to uniquely identify him, and safely exchanges keys with the video service's servers. [<a title="keygen-assym">KEYGEN-ASSYM</a> | <a title="keyex">KEYEX</a> | <a title="keycall">KEYCALL</a> | <a title="sign">SIGN</a> | <a title="verify">VERIFY</a>]</p>
 <p>The video service provider is able to track the number of devices Ryan has connected to the service by virtue of the pre-provisioned keys and identifiers, so that when he attempts to connect a sixth device, the service can prompt him to upgrade his service level or deactivate one of the existing devices. [<a title="keycall">KEYCALL</a> | <a title="namedkey">NAMEDKEY</a>]</p>
 <p> Ryan finally attempts to play some video through the service. By virtue of the secure connection, the video service provider is able to make content authorization decisions that are tailored to the security capabilities of the exact make, model and version of TV that Ryan has purchased, thereby ensuring that the content providers security requirements are met in respect of the specific content requested. Ryan's devices send encrypted messages about quality of service and watching behavior to the video service provider. [<a title="namedkey">NAMEDKEY</a> | <a title="keycall">KEYCALL</a> | <a title="sign">SIGN</a> | <a title="verify">VERIFY</a> | <a title="mac">MAC</a> | <a title="wrap">WRAP</a> | <a title="encrypt">ENCRYPT</a>]</p>
 </section>
 <section>
   <h2>Code Sanctity and Bandwidth Saver</h2>
-<p>A major social networking site wishes to optimize website performance by storing JavaScript libraries that are served from a CDN in <code>localStorage</code> or in <code>IndexedDB</code> [[INDEXEDDB]], preventing server rountrips to the CDN.  When the code in the libraries has undergone critical modifications, the social networking site wishes to determine whether the version stored in the client needs updating.  </p>
-<p>Using the Web Crypto API, the social networking site might verify a digest of the code from the CDN and compare it to a digest of the code in <code>localStorage</code>.  The social network can generate a digest of the material extracted from the client storage, and compare this to a pristine version of the digest that the social networking site makes available to the client. If the two digests match, the code is deemed the latest from the CDN, and does not need to be refreshed. [<a title="digest">DIGEST</a>]</p>
+<p>A major social networking site wishes to optimize website performance by storing JavaScript libraries that are served from a CDN in <code>localStorage</code> [[webstorage]] or in <code>IndexedDB</code> [[INDEXEDDB]], preventing server rountrips to the CDN.  When the code in the libraries has undergone critical modifications, the social networking site wishes to determine whether the version stored in the client needs updating.  </p>
+<p>Using the Web Crypto API, the social networking site might verify a digest of the code from the CDN and compare it to a digest of the code in <code>localStorage</code> [[webstorage]].  The social network can generate a digest of the material extracted from the client storage, and compare this to a pristine version of the digest that the social networking site makes available to the client. If the two digests match, the code is deemed the latest from the CDN, and does not need to be refreshed. [<a title="digest">DIGEST</a>]</p>
 <pre class="example highlight prettyprint">
 // Retrieve a SHA-256 digest of the pristine version of the code
 // This is retrieved from the server
@@ -287,7 +293,7 @@
   <h2>Encrypted Communications via Webmail</h2>
   <p>Tantek wishes to communicate with Ryan securely. Moreover, Tantek wishes to use an email web application (EWA) provided by a third party, which is a web site that allows users who have accounts to set up email accounts of their own choosing -- that is, users can enter in existing POP/IMAP/SMTP username and password credentials, or simply use an email address provided by the EWA at its own address. The EWA serves to send messages, as well as provide a message store available from anywhere. It allows for the possibility of sending encrypted messages.</p>
   <p>Ryan provides a PGP key on his website, encoded in the relevant conventions. For instance, he follows the common practice of including a Base64 text string that represents his public key.</p>
-  <p>Ryan uses the hCard format [[hCard]] to encapsulate contact information with some semantic annotation within the markup of his webpage. Within the hCard ([[hCard]]), he does something like this:</p>
+  <p>Ryan uses the hCard format [[hCard]] to encapsulate contact information with some semantic annotation within the markup of his webpage. Within the hCard ([[hCard]]), he may include a snippet like this:</p>
   <pre class="example highlight prettyprint">
     
     &lt;span class="key">
@@ -348,9 +354,10 @@
 <section>
   <h2>Off The Record Real Time Messaging</h2>
   <p>David and Nadim wish to have an "Off The Record" chat in real time, completely between them, primarily using text, as well as the ability to share digital data such as photographs. They log on to a chat server, and connect to each other's machines directly. The server merely serves up the UI for the chat client, and does not log their conversation (and in fact, cannot). The respective web pages on David and Nadim's browsers may use the WebCrypto API to do the following things:</p>
+  <div class="issue">ISSUE: The OTR use case needs more protocol breakdown, including possible use of Socialist Millionaire methodology.  Additionally, references may need to be added to the respec - biblio.js for OTR and for the Socialist Millionaire protocol; currently, this seems normative: <a href="http://www.cypherpunks.ca/otr/Protocol-v3-4.0.0.html">http://www.cypherpunks.ca/otr/Protocol-v3-4.0.0.html</a>. </div>
   <ol>
     <li>Generate assymetric keys for David and Nadim respectively, such that both get public and private keys. [<a title="derive-assym">DERIVE-ASSYM</a>]</li>
-    <li>Engage in a key exchange, so that David and Nadim get each other's public keys. It is conceivable that using the WebCrypto API the chat application can enable David and Nadim to use a Diffie-Hellman key exchange, or a mechanism such as SIGMA [cf.OTR] over WebSockets [!HTML]. The key exchange which accompanies message exchanges involves the generation of cryptographically secure random numbers. [<a title="random">RANDOM</a> | <a title="keyex">KEYEX</a> | <a title="keyex-dh">KEYEX-DH</a>]</li>
+    <li>Engage in a key exchange, so that David and Nadim get each other's public keys. It is conceivable that using the WebCrypto API the chat application can enable David and Nadim to use a Diffie-Hellman key exchange, or a mechanism such as SIGMA over WebSockets [[WEBSOCKETS-API]][[WEBSOCKETS-PROTOCOL]]. The key exchange which accompanies message exchanges involves the generation of cryptographically secure random numbers. [<a title="random">RANDOM</a> | <a title="keyex">KEYEX</a> | <a title="keyex-dh">KEYEX-DH</a>]</li>
     <li>David or Nadim may now compose a message to each other. Each message exchange involves authentication, message authentication codes, further key derivation, and further key exchanges. [<a title="sign">SIGN</a> | <a title="verify">VERIFY</a> | <a title="mac">MAC</a> | <a title="random">RANDOM</a> | <a title="derive">DERIVE</a> | <a title="keyex">KEYEX</a> | <a title="keyex-dh">KEYEX-DH</a>] </li>
   </ol>
 </section>
@@ -358,8 +365,8 @@
 <h2>Documents In The Cloud</h2>
 <p>Vijay wishes to confidentially store certain documents of various file types using a web service that he pays a monthly subscription to for such confidential storage. The confidential storage web application (abbreviated "SWA") makes the claim that all storage is encrypted, and that even it cannot access the contents of what a user stores. He can drag and drop content from his laptop onto a web page of the service, and it automatically encrypts it and stores it in an encrypted manner. Vijay can do the following:</p>
 <ol>
-<li>Log on to the service using his credentials; after the service determines that Vijay is using his primary browser, which he will use to access the service subsequently, it generates both signature and encryption key pairs. Derivation may be similar to the banking use case. [<a title="derive-assym">DERIVE-ASSYM</a> | <a title="keyex-dh">KEYEX-DH</a> | <a title="verify">VERIFY</a> | <a title="unwrap">UNWRAP</a> | <a title="decrypt-sym">DECRYPT-SYM</a> | <a title="sign">SIGN</a>] </li>
-<li>Drag over content from his underlying file system that he wishes to store. The SWA encrypts the content, and uploads it. It may make multipart cryptographic operations on a given file, and it may also "chunk upload" large content, depending on file-size. [<a title="sign">SIGN</a> | <a title="hmac">HMAC</a> | <a title="derive-sym">DERIVE-SYM</a> | <a title="encrypt-sym">ENCRYPT-SYM</a> | <a title="keycall">KEYCALL</a> | <a title="wrap">WRAP</a>] </li>   
+<li>Log on to the service using his credentials; after the service determines that Vijay is using his primary browser, which he will use to access the service subsequently, it generates both signature and encryption key pairs. Key generation may be similar to the banking use case. [<a title="derive-assym">KEYGEN-ASSYM</a> | <a title="keyex-dh">KEYEX-DH</a> | <a title="verify">VERIFY</a> | <a title="unwrap">UNWRAP</a> | <a title="decrypt-sym">DECRYPT-SYM</a> | <a title="sign">SIGN</a>] </li>
+<li>Drag over content from his underlying file system that he wishes to store. The SWA signs and encrypts the content, and uploads it. It may make multipart cryptographic operations on a given file, and it may also "chunk upload" large content, depending on file-size. [<a title="sign">SIGN</a> | <a title="hmac">HMAC</a> | <a title="derive-sym">DERIVE-SYM</a> | <a title="encrypt-sym">ENCRYPT-SYM</a> | <a title="keycall">KEYCALL</a> | <a title="wrap">WRAP</a>] </li>   
 <li>Store that content on the server, with the assurance that it is stored there in a way that is virtually undecipherable to third-parties, including those running the SWA.</li>
 <li>Later, Vijay can retrieve the content, and save it back to his local file system. He has the assurance that the content has not been tampered with since it was stored, and that it in fact is from SWA. [<a title="keycall">KEYCALL</a> | <a title="verify">VERIFY</a> | <a title="hmac">HMAC</a> | <a title="unwrap">UNWRAP</a> | <a title="decrypt-sym">DECRYPT-SYM</a>] </li> 
 </ol>
@@ -368,14 +375,14 @@
     <section>
 <h2>BrowserID: Use of Cryptography for Identity Protocols</h2>
 <p>
-Karen, an avid photographer, has been looking for a site to store all the photos that she posts on various websites.  Instead of creating yet another online identity for another photo storage website, Karen is pleased to find a photo-storage service that uses the BrowserID protocol [[BrowserID]], allowing her to use any email address as an identity.  The photo-storage service (PSS) is a <em>Relying Party</em> of the protocol, and Karen elects to use Persona.org as an <em>Identity Provider</em>, since she sees a "log-in with Persona" button on the PSS website.  She notes that her preferred email provider is not yet an Identity Provider for use with BrowserID [[BrowserID]], and thus uses Persona.org as a fallback option.
+Karen, an avid photographer, has been looking for a site to store all the photos that she posts on various websites.  Instead of creating yet another online identity for another photo storage website, Karen is pleased to find a photo-storage service that uses the BrowserID protocol [[BrowserID]], allowing her to use any email address as an identity.  The photo-storage service (PSS) is a <em>Relying Party</em> of the protocol, and Karen elects to use Persona.org as an <em>Identity Provider</em>, since she sees a "log-in with Persona" button on the PSS website.  She notes that her preferred email provider is not yet an Identity Provider for use with BrowserID [[BrowserID]], and thus uses Persona.org as an interim or fallback option.
 </p>
 <p>
 Karen first creates a "verified email" identity with Persona.org.  Persona.org sends out an email with a hyperlink in it to an email address that she chooses to use as one of her identities (she chooses "karen@webcrypto.com"), especially for use with PSS.  She then logs in to this email account and clicks on the verification link sent by Persona.org.  Persona.org is thus able to determine that Karen owns this email address.  The following now happens:</p>
 <ol>
 <li><p>Persona.org creates assymetric keys, public and private, on behalf of the user. [<a title="keygen-assym">KEYGEN-ASSYM</a>]</p></li>
-<li><p>Persona.org's web page then sends the public key just created over TLS for storage on Persona.org's servers, and stores the keypair in the browser's client-side storage.  This could include [[INDEXEDDB]] and <code>localStorage</code>, although in browsers with a native implementation of BrowserID [[BrowserID]], this might include another key store.</p></li>
-<li><p>Persona.org then generates a certificate, which involves signing the public key just created, the email address, and a validity interval; the signature here is performed by Persona.org.  This certificate takes the form of a [[JWT]] object. The [[JWT]] object -- the certificate created above -- is itself stored in the browser's client storage, which can be [[INDEXEDDB]] or <code>localStore</code>; if the browser implementation has a native implementation of [[BrowserID]], another key and certificate store could exist. [<a title="keycall">KEYCALL</a> | <a title="sign">SIGN</a>]</p></li>
+<li><p>Persona.org's web page then sends the public key just created over TLS for storage on Persona.org's servers, and stores the keypair in the browser's client-side storage.  This could include [[INDEXEDDB]] and <code>localStorage</code> [[webstorage]], although in browsers with a native implementation of BrowserID [[BrowserID]], this might include another key store.</p></li>
+<li><p>Persona.org then generates a certificate, which involves signing the public key just created, the email address, and a validity interval; the signature here is performed by Persona.org.  This certificate takes the form of a JSON Web Token [[JWT]] object. The [[JWT]] object -- the certificate created above -- is itself stored in the browser's client storage, which can be [[INDEXEDDB]] or <code>localStore</code> [[webstorage]]; if the browser implementation has a native implementation of [[BrowserID]], another key and certificate store could exist. [<a title="keycall">KEYCALL</a> | <a title="sign">SIGN</a>]</p></li>
 </ol>
 <p>Karen now has at least one identity, namely her email of choice, verified on Persona.org, along with a certificate issued by Persona.org.  She then decides to log in to the PSS website using that identity.  The following sequence then takes place:</p>
 <ol>
@@ -411,17 +418,18 @@
    2. Obtain the karen@webcrypto.com private key for signing assertion from client-side storage
    3. Send the certificate structure assertionPlusCert over for verification
    
-   Caveat emptor: step 3 can be made more efficient in terms of Web Crypto API usage if
+   Caveat emptor: step 3 can be made more efficient in terms of WebCrypto API usage if
    Karen's public key can be sent over using the structured clone algorithm.  Currently
    we proceed with it as a JWK embedded in a JWT.
 
 **/
 
+// Retrieve Karens public key
 
 transaction.objectStore("publicBrowserIDKeys").get("karen@webcrypto.com").onsuccess = function(evt) {
   var privateKey = event.target.result;
 
-// Sign the assertion -- see signature example (TODO)
+// Sign the assertion -- signature syntax resembles verification syntax in banking example
 // Send the assertionPlusCert structure to script on photosharingsite.example
 
   pssHandle.postMessage(assertionPlusCert, "http://photosharingsite.example");
@@ -519,7 +527,7 @@
 </li>
 <li><p>The PSS website receives the message, sent via cross-origin messaging, and proceeds to validate the assertion.  In order to do this, the PSS website first obtains Persona.org's public key, hosted at a well-known location, and verifies the signature on the certificate.  The script at PSS may choose to "import" the public key of Persona.org in order to verify the signature, and store it within PSS's application storage. [<a title="import">IMPORT</a> | <a title="verify">VERIFY</a>]</p>
 </li>
-<li><p>The PSS website then verifies the signature of the user on the assertion.  Karen's public key has also been sent to script hosted on PSS via a structured clone using cross-document messaging. [<a title="verify">VERIFY</a>]</p></li>
+<li><p>The PSS website then verifies the signature of the user on the assertion.  Karen's public key has also been sent to script hosted on PSS. [<a title="verify">VERIFY</a>]</p></li>
 <li>Upon successful verification of both signatures, Karen is granted access to PSS, which now identifies her and considers her authenticated.</li>
 </ol>