highlevel-api-source.html
author David Dahl <ddahl@mozilla.com>
Fri, 25 Jan 2013 10:22:21 -0600
changeset 1 f58f6b8aa0a0
parent 0 30d26e80c3e9
child 2 b63f163cc987
permissions -rw-r--r--
Added protect and unprotect, changed some args from typedarray to DOMstring
<!DOCTYPE html>
<html>
  <head>
    <title>WebCrypto High-level API</title>
    <meta http-equiv='Content-Type' content='text/html;charset=utf-8'/>
    <style>
      table {
        border-collapse: collapse;
        border-spacing: 0px;
        margin-top: +1em;
        margin-bottom: +1em;
        border-color: black;
        font-family: "Courier New", Inconsolata, "Bitstream Charter";
        font-size: 90%;
      }
      th {
        background-color:DimGray;
        color:white;
        font-weight: normal;
      }
      .sub-th {
        background-color: Linen;
        font-style: italic;
      }
      .centered {
        text-align: center;
      }
      .first-column {
        background-color: Beige;
        font-weight: bold;
      }
      .excluded-first-column {
        background-color: DarkGray;
        text-decoration: line-through;
      }
    </style>
    
    <!-- 
      === NOTA BENE ===
      For the three scripts below, if your spec resides on dev.w3 you can check them
      out in the same tree and use relative links so that they'll work offline,
     -->
    <script src='http://www.w3.org/Tools/respec/respec-w3c-common' class='remove' async></script>
    <script type="text/javascript" class='remove'>
      var respecConfig = {  specStatus: "WD",
                            shortName: "webcrypto-high-level-api",
                            editors: [{ name: "David Dahl", 
                                        mailto: "ddahl@mozilla.com", 
                                        company: "Mozilla Corporation", 
                                        companyURL: "http://www.mozilla.org/"} ],
                            publishDate: "2013-01-25",
                            previousPublishDate:  "2013-01-22",
                            // edEnd:  "",
                            previousMaturity: "ED",
                            edDraftURI:   "https://dvcs.w3.org/hg/webcrypto-highlevel/raw-file/tip/Overview.html",
                            wg:           "Web Cryptography WG",
                            wgURI:        "http://www.w3.org/2012/webcrypto/",
                            wgPublicList: "public-webcrypto",
                            wgPatentURI:  "http://www.w3.org/2004/01/pp-impl/54174/status",
                            localBiblio : { "WEBCRYPTO" : "Ryan Sleevi, David Dahl. <a href=\"http://www.w3.org/TR/WebCryptoAPI/\"><cite>Web Cryptography API.</cite></a> W3C Working Draft (Work in progress.) URL: <a href=\"http://www.w3.org/TR/WebCryptoAPI/\">http://www.w3.org/TR/WebCryptoAPI/</a> "}
                        };
    </script>
  </head>
  <body>
    <section id='abstract'>
      <p>This specification describes a JavaScript API for public key generation, encryption, decryption, digital signature generation and verification, and hashing.
      </p>
    </section>
    
    <section id="sotd">
      <p>This document is the First Public Working Draft of the WebCrypto High-level API recommendation. It defines an API that provides access to named origin-specific pre-provisioned keys.</p>
    </section>
    
    <section class="informative">
      <h2>Introduction</h2>
      <p>
        The Web Cryptography API [[!WEBCRYPTO]] describes a JavaScript API for performing basic cryptographic operations in web applications. The Web Cryoptography API is not a simple API geared towards the average web developer, rather its use requires near-expert knowledge of cryptography. The 'High-level' API described here is designed around fewer use cases and is not concerned with backward-compatibility with existing crypto systems and protocols. This API leverages the IETF JOSE JWA, JWK and JWE JSON formats for algorithms, public keys and cipher data.
      </p>
    </section>
    
    <section>
        <h2>Use cases</h2>
        <section>
          <h3>Security of data at rest</h3>
          <p>TODO</p>
        </section>
        <section>
          <h3>Web-based messaging</h3>
          <p>TODO</p>
        </section>
    </section>
    
    <section id="conformance">
      <p>
          The following conformance classes are defined by this specification:
        </p>
        <dl>
          <dt><dfn>conforming user agent</dfn></dt>
          <dd>
            <p>
              A user agent is considered to be a conforming user agent
              if it satisfies all of the MUST-, REQUIRED- and SHALL-level
              criteria in this specification that apply to implementation. This specification
              uses both the terms "conforming user agent" and "user agent" to refer to this
              product class.
            </p>
            <p>
              User agents MAY implement algorithms in this
              specification in any way desired, so long as the end result is indistinguishable
              from the result that would be obtained from the specification's algorithms.
            </p>
          </dd>         
        </dl>
        <p>
          User agents that use ECMAScript to implement the APIs defined in this specification
          MUST implement them in a manner consistent with the
          ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]]
          as this specification uses that specification and terminology.
        </p>
      
    </section>
    
    <section id="scope" class="informative">
      <h2>Scope</h2>
      <p>The considerations in the Scope section of [[!WEBCRYPTO]] apply to this specification as well.
      </p>
    </section>
    <section class="informative">
      <h2>Privacy considerations</h2>
      <p>The Privacy considerations of [[!WEBCRYPTO]] apply to this specification.</p>
      <section>
          <p>
            TBD
          </p>
      </section>
    </section>
    
    <section class="section" id="dependencies">
      <h3>Dependencies</h3>
      <p>
        This specification relies on several other underlying specifications. 
      </p>
      <dl>
        <dt>HTML5</dt>
        <dd>The terms and algorithms
          <dfn title="Window"><code>Window</code></dfn>,
          <dfn title="Function"><code>Function</code></dfn>,
          <dfn>origin</dfn>, <dfn>same origin</dfn>, <dfn>structured clone</dfn>,
          <dfn>structured clone algorithm</dfn>, <dfn>task</dfn>, <dfn>task source</dfn>, 
          <dfn title="queue-a-task">queue a task</dfn>
          and <dfn title="fire-a-simple-event">fire a simple event</dfn> are defined by the HTML 5 
          specification [[!HTML5]].
        </dd>
        <dt>WebIDL</dt>
        <dd>Many of the interface definitions and all of the IDL in this spec depends on [[!WEBIDL]].</dd>
        <dt>WebWorkers</dt>
        <dd>The term <dfn title="WorkerGlobalScope"><a class="externalDFN"><code>WorkerGlobalScope</code></a></dfn> is defined by
        the WebWorkers specification [[!WEBWORKERS]].</dd>
      </dl>
    </section>

    <section>
      <h2>API definition</h2>
      <section class="informative">
        <h3>Overview</h3>
        <p>This specification defines a new <a><code>highlevel</code></a> attribute on the <a><code>Window.crypto</code></a> and <a><code>WorkerGlobalScope</code></a> objects. 
      </section>
      
      <section>
        <h3>Extension of Crypto interface</h3>
        <dl title="partial interface Crypto" class="idl">
          <dt>readonly attribute Highlevel highlevel</dt>
          <dd>The object that exposes the high-level API</dd>
      </dl>
      </section>

      <section>
        <h3>Highlevel interface</h3>
        <dl title="interface Highlevel" class="idl">
          <dt>void getPublicKey (in DOMString aJWKID)</dt>
          <dd>Get public key by an ID if it exists</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onGetKeypair</dt>
          <dd>onGetKeypair event handler</dd>
          <dt>void createKeyPair (in DOMString aJoseAlgID)</dt>
          <dd>Generate a public keypair</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onCreateKeypair</dt>
          <dd>onCreateKeypair event handler</dd>

          <dt>void encryptAndSign (in DOMSring aPlainText, in DOMString aRecipientJWK, in DOMString aSenderJWKID)</dt>
          <dd>Perform encryption, signing the encrypted data</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onEncryptComplete</dt>
          <dd>onEncryptComplete event handler</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onEncryptError</dt>
          <dd>onEncryptError event handler</dd>

          <dt>void verifyAndDecrypt (in DOMString aReceivedJWE, in DOMString aSenderJWK, in DOMString aRecipientJWKID)</dt>
          <dd>Verify signature and decrypttion method</dd>          
          <dt>[TreatNonCallableAsNull] attribute Function? onDecryptComplete</dt>
          <dd>onDecryptComplete event handler</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onDecryptError</dt>
          <dd>onDecryptError event handler</dd>

          <dt>void protect (in DOMString aPlainText, in DOMString aJWAlgID)</dt>
          <dd>Symmetric encryption of a string (a key is generated on each use)</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onProtectComplete</dt>
          <dd>onProtectComplete event handler, ciphertext and keyID are passed to this function</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onProtectError</dt>
          <dd>onProtectError event handler</dd>

          <dt>void unprotect (in DOMString aKeyID, in DOMString aPlainText)</dt>
          <dd>Symmetric decryption of a string</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onUnprotectComplete</dt>
          <dd>onUnprotectComplete event handler</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onUnprotectError</dt>
          <dd>onUnprotectError event handler</dd>

          <dt>void sign(in aDOMString aClearData, in DOMString aJWKID)</dt>
          <dd>Create a digital signature</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onSignComplete</dt>
          <dd>onSignComplete event handler</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onSignError</dt>
          <dd>onSignError event handler</dd>

          <dt>void verify (in DOMString aJWS, in DOMString aDataToVerify, in DOMString aJWK)</dt>
          <dd>Verify a digital signature</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onVerifyComplete</dt>
          <dd>onVerifyComplete event handler</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onVerifyError</dt>
          <dd>onVerifyError event handler</dd>

          <dt>void hash(in DOMString aData)</dt>
          <dd>Create a cryptographic hash</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onHashComplete</dt>
          <dd>onHashComplete event handler</dd>
          <dt>[TreatNonCallableAsNull] attribute Function? onHashError</dt>
          <dd>onHashError event handler</dd>
        </dl>
      </section>
      
      <section>
        <h3>Extension of WorkerGlobalScope interface</h3>
        <dl title="partial interface WorkerGlobalScope" class="idl">
          <dt>readonly attribute Highlevel highlevel</dt>
          <dd>The object that exposes the high-level API</dd>
        </dl>
      </section>

    </section>
    
    <section>
      <h2>Examples</h2>
      <h3>Keypair handling, generation</h3>
      <pre class="example sh_html sh_sourceCode">
var myCurrentKeyPair = null;

function onGetKeypair(aKeypair)
{
  localStorage.setItem(aKeypair.id, aKeypair.publicKey);
}

var cryptoAPI = new window.crypto.highlevel();
cryptoAPI.onGetKeypair = onGetKeypair;

function onCreateKeypair(aKeypair)
{
  localStorage.setItem(aKeypair.id, aKeypair.publicKey);
  myCurrentKeyPair = aKeypair;
}

cryptoAPI.onCreateKeypair = onCreateKeypair;

cryptoAPI.createKeypair("RSA1_5");
</pre>
      <h3>Public Key Encryption</h3>
<pre class="example sh_html sh_sourceCode">
var plainText = "The rain in Spain falls mainly on the plain.";

function onEncryptComplete(aJWE, aPublicKey){
  // send cipher data to the server for storage, etc...
}
cryptoAPI.onEncryptComplete = onEncryptComplete;
cryptoAPI.encryptAndSign(plainText, RECIPIENT_JWK, SENDER_JWK_ID);
</pre>

<h3>Public Key Decryption</h3>
<pre class="example sh_html sh_sourceCode">
function onDecryptComplete(aPlainText) {
  // read and save plain text
}

function onDecryptError(aException) {
  // examine exception raised, re-throw or throw a new error
}
cryptoAPI.onDecryptError = onDecryptError;

// we have recvd a new cipher message...
// set the event handler
cryptoAPI.onDecryptComplete = onDecryptComplete;
// verfiy and decrypt - if verification or decryption fails, onDecryptError is fired
cryptoAPI.verifyAndDecrypt(RECEIVED_JWE, SENDER_JWK, RECIPIENT_JWK_ID);
</pre>

<h3>Symmetric Encryption</h3>
<pre class="example sh_html sh_sourceCode">
function onProtectComplete(aCipherText, aKeyID) {
  // cipher text and the key ID are provided to this event handler
}

function onProtectError(aException) {
  // examine exception or error message
}
cryptoAPI.onProtectError = onProtectError;

cryptoAPI.onProtectComplete = onProtectComplete;
// 
cryptoAPI.protect("s3kr3t m355ag3", "A256GCM");
</pre>

<h3>Symmetric Decryption</h3>
<pre class="example sh_html sh_sourceCode">
function onUnprotectComplete(aPlainText) {
  savePlainTextToLocalStorage(aPlainText);
}

function onUnprotectError(aException) {
  // examine exception or error message
}
cryptoAPI.onUnprotectError = onUnprotectError;

cryptoAPI.onUnprotectComplete = onUnprotectComplete;

cryptoAPI.unprotect(keyID, cipherString);
</pre>

<h3>Signature creation</h3>
<pre class="example sh_html sh_sourceCode">
var dataToSign = "This is some data to sign";

cryptoAPI.onSignComplete = function (aJWS) {
  // send the signature to the server, etc.
};

cryptoAPI.onSignError = function (aError) {
  // console.log(), etc.
};

cryptoAPI.sign(dataToSign, JWK_ID);
</pre>

<h3>Signature Verification</h3>
<pre class="example sh_html sh_sourceCode">
cryptoAPI.onVerifyComplete = function (aVerified) {
  // aVerified is a boolean
};

cryptoAPI.onVerifyError = function (aError) {
  // console.log(), etc.
};

cryptoAPI.verify(RECEIVED_JWS, SIGNER_JWK);        
</pre>        
      </section> 
    </section>
    <!--
    <section class='appendix'>
      <h2>Acknowledgements</h2>
      <p>
        Many thanks to ...
      </p>
    </section>
    -->
  </body>
</html>