encboot.mx raw

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