encboot.mx raw

   1  package main
   2  
   3  import (
   4  	"git.smesh.lol/smesh/web/common/crypto/hkdf"
   5  	"git.smesh.lol/smesh/web/common/helpers"
   6  	"git.smesh.lol/smesh/web/common/jsbridge/dom"
   7  	"git.smesh.lol/smesh/web/common/jsbridge/localstorage"
   8  	"git.smesh.lol/smesh/web/common/jsbridge/signer"
   9  	"git.smesh.lol/smesh/web/common/jsbridge/subtle"
  10  )
  11  
  12  const lsEncKeyPrefix = "smesh-enc-epk-"
  13  
  14  var encKeyHex string // hex symmetric key, sent to SW
  15  
  16  // bootstrapEncKey derives the IDB encryption key and calls done when ready.
  17  // First run: generates ephemeral keypair, ECDH via signer, stores ephemeral pubkey.
  18  // Reload: reads stored ephemeral pubkey, ECDH via signer.
  19  func bootstrapEncKey(done func()) {
  20  	lsKey := lsEncKeyPrefix | pubhex
  21  	epkHex := localstorage.GetItem(lsKey)
  22  	if epkHex == "" {
  23  		// First run: generate ephemeral secret, derive pubkey via signer.
  24  		var sec [32]byte
  25  		subtle.RandomBytes(sec[:])
  26  		secHex := helpers.HexEncode(sec[:])
  27  		for i := range sec {
  28  			sec[i] = 0
  29  		}
  30  		signer.PubkeyFromSecret(secHex, func(pkHex string) {
  31  			if pkHex == "" {
  32  				dom.ConsoleLog("enc: PubkeyFromSecret failed")
  33  				done()
  34  				return
  35  			}
  36  			localstorage.SetItem(lsKey, pkHex)
  37  			// ECDH(user_seckey, ephemeral_pubkey) via signer's active identity.
  38  			signer.GetSharedSecret(pkHex, func(sharedHex string) {
  39  				if sharedHex == "" {
  40  					dom.ConsoleLog("enc: getSharedSecret failed")
  41  					done()
  42  					return
  43  				}
  44  				deriveAndSetEncKey(sharedHex, done)
  45  			})
  46  		})
  47  		return
  48  	}
  49  	// Reload: ask signer for ECDH(user_seckey, ephemeral_pubkey).
  50  	signer.GetSharedSecret(epkHex, func(sharedHex string) {
  51  		if sharedHex == "" {
  52  			dom.ConsoleLog("enc: getSharedSecret failed")
  53  			done()
  54  			return
  55  		}
  56  		deriveAndSetEncKey(sharedHex, done)
  57  	})
  58  }
  59  
  60  func deriveAndSetEncKey(sharedHex string, done func()) {
  61  	shared := helpers.HexDecode(sharedHex)
  62  	prk := hkdf.Extract(nil, shared)
  63  	symKey := hkdf.Expand(prk[:], []byte("smesh-idb-enc"), 32)
  64  	encKeyHex = helpers.HexEncode(symKey)
  65  	dom.IDBSetEncKey(encKeyHex)
  66  	dom.ConsoleLog("enc: IDB encryption key set")
  67  	done()
  68  }
  69  
  70  // sendEncKeyToSW sends the encryption key to the service worker.
  71  func sendEncKeyToSW() {
  72  	if encKeyHex != "" {
  73  		dom.PostToSW("[\"ENC_KEY\"," | jstr(encKeyHex) | "]")
  74  	}
  75  }
  76