@@ -3,6 +3,7 @@ package keymanager
33import (
44 "context"
55 "crypto/ecdsa"
6+ "crypto/rand"
67 "encoding/hex"
78 "errors"
89 "fmt"
@@ -29,20 +30,38 @@ const (
2930 EMPTY = espressotee .EMPTY
3031)
3132
33+ var FatalErrUnableToRegisterSigner = errors .New ("unable to register signer" )
34+
35+ type KeyManagerState int
36+
37+ const (
38+ Init KeyManagerState = iota
39+ PendingRegistration
40+ Registered
41+ )
42+
43+ type state struct {
44+ currentState KeyManagerState
45+ attestation []byte
46+ data []byte
47+ }
48+
3249// This is a private key derived from the test test test ... test junk BIP-39 mnemonic. It is a well known private key, so it should be fine to hardcode for tests.
3350// I found it here: https://ethereum.stackexchange.com/questions/147078/hardhat-which-file-is-initial-state-in-such-as-the-mnemonic-and-20-accounts
3451const TEST_PERSISTENT_KEY = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
3552const quoteFile = "/dev/attestation/quote"
3653const userDataAttestationFile = "/dev/attestation/user_report_data"
3754
3855type EspressoKeyManagerInterface interface {
39- HasRegistered () bool
40- Register (getAttestationFunc func ([]byte ) ([]byte , error )) error
4156 RegisterService () error
57+ Init () error
4258 GetCurrentKey () * ecdsa.PublicKey
4359 SignPayload (message []byte ) ([]byte , error )
4460 SignMessage (message []byte ) ([]byte , error )
4561 TeeType () espressotee.TEE
62+ GetKeyManagerState () KeyManagerState
63+ CheckRegistration () (bool , error )
64+ InitRegistration (getAttestationFunc func ([]byte ) ([]byte , error )) error
4665}
4766
4867var _ EspressoKeyManagerInterface = & EspressoKeyManager {}
@@ -56,8 +75,8 @@ type EspressoKeyManager struct {
5675 teeType espressotee.TEE
5776 serviceType espressotee.ServiceType
5877
59- hasRegistered bool
6078 espressoNitroAttestationVerifierClient * attestationverifierclient.EspressoAttestationVerifierClient
79+ state state
6180}
6281
6382func NewEspressoKeyManager (
@@ -78,7 +97,12 @@ func NewEspressoKeyManager(
7897 // is provided, we use that one. Otherwise, we read the enclave private key from the attestation path.
7998 // Note: The current implementation only supports reading the key during key manager construction
8099 // for the batch poster. Support for reading the caff node key will be added in a later PR.
81- if keyPairAttestationsPath != "" && chainID != 0 {
100+ if teeType == espressotee .SGX {
101+ privKey , err = ecdsa .GenerateKey (crypto .S256 (), rand .Reader )
102+ if err != nil {
103+ panic (err )
104+ }
105+ } else if keyPairAttestationsPath != "" && chainID != 0 {
82106 // Read enclave private key
83107 privKey , err = espresso_tee_utils .ReadEnclavePrivateKey (keyPairAttestationsPath , chainID )
84108 if err != nil {
@@ -120,15 +144,24 @@ func NewEspressoKeyManager(
120144 teeType : teeType ,
121145 serviceType : serviceType ,
122146 espressoNitroAttestationVerifierClient : espressoNitroAttestationVerifierClient ,
147+ state : state {
148+ currentState : Init ,
149+ attestation : []byte {},
150+ data : []byte {},
151+ },
123152 }
124153}
125154
126- func (k * EspressoKeyManager ) HasRegistered () bool {
127- return k .hasRegistered
155+ func (k * EspressoKeyManager ) hasRegistered () bool {
156+ return k .state .currentState == Registered
157+ }
158+
159+ func (k * EspressoKeyManager ) GetKeyManagerState () KeyManagerState {
160+ return k .state .currentState
128161}
129162
130163func (k * EspressoKeyManager ) VerifyRegistered () (bool , error ) {
131- if k .hasRegistered {
164+ if k .hasRegistered () {
132165 return true , nil
133166 }
134167 pubKey , ok := k .privKey .Public ().(* ecdsa.PublicKey )
@@ -143,6 +176,30 @@ func (k *EspressoKeyManager) VerifyRegistered() (bool, error) {
143176 return ok , nil
144177}
145178
179+ func (k * EspressoKeyManager ) CheckRegistration () (bool , error ) {
180+ state := k .state .currentState
181+ switch state {
182+ case Init :
183+ log .Warn ("ephemeral keys are not yet registered in Espresso TEE Contract, KeyManager in Init phase. Waiting for Zk proof to be generated" )
184+ err := k .Init ()
185+ if err != nil {
186+ return false , fmt .Errorf ("unable to init keymanager: %w" , err )
187+ }
188+ return false , nil
189+ case PendingRegistration :
190+ log .Warn ("ephemeral keys are not yet registered in Espresso TEE Contract, KeyManager in Registration phase" )
191+ err := k .RegisterService ()
192+ if err != nil {
193+ return false , fmt .Errorf ("%w: %w" , FatalErrUnableToRegisterSigner , err )
194+ }
195+ return false , nil
196+ case Registered :
197+ return true , nil
198+ default :
199+ return false , fmt .Errorf ("key manager in an unknown state: %v" , state )
200+ }
201+ }
202+
146203/*
147204 * This function will get the attestation in order to properly register the signing address on chain for a given TEE type
148205 */
@@ -201,20 +258,28 @@ func (k *EspressoKeyManager) PrepareRegisterService(getAttestationFunc func([]by
201258 }
202259}
203260
204- func (k * EspressoKeyManager ) Register (getAttestationFunc func ([]byte ) ([]byte , error )) error {
205- if k .hasRegistered {
261+ func (k * EspressoKeyManager ) InitRegistration (getAttestationFunc func ([]byte ) ([]byte , error )) error {
262+ if k .hasRegistered () {
206263 log .Info ("EspressoKeyManager already registered" )
207264 return nil
208265 }
209266
267+ // In tests we use TESTS tee type but the contract only accepts SGX tee type
268+ if k .teeType == TESTS && k .serviceType != espressotee .Test {
269+ k .teeType = SGX
270+ }
271+
210272 // Check on-chain if we have already registered
211273 hasRegistered , err := k .VerifyRegistered ()
212274 if err != nil {
213275 return err
214276 }
215277 if hasRegistered {
216- k .hasRegistered = true
217- log .Info ("Signer already registered on-chain" )
278+ k .state .currentState = Registered
279+ k .state .attestation = []byte {}
280+ k .state .data = []byte {}
281+ signerAddr := crypto .PubkeyToAddress (k .privKey .PublicKey )
282+ log .Info ("Signer already registered on-chain" , "signer address" , signerAddr .Hex ())
218283 return nil
219284 }
220285
@@ -223,7 +288,18 @@ func (k *EspressoKeyManager) Register(getAttestationFunc func([]byte) ([]byte, e
223288 if err != nil {
224289 return err
225290 }
226- err = k .espressoTEEVerifierCaller .RegisterService (k .dataPoster , attestation , data , uint8 (k .teeType ), k .serviceType )
291+ k .state .currentState = PendingRegistration
292+ k .state .attestation = attestation
293+ k .state .data = data
294+ return nil
295+ }
296+
297+ func (k * EspressoKeyManager ) RegisterService () error {
298+ currentState := k .GetKeyManagerState ()
299+ if currentState != PendingRegistration {
300+ return fmt .Errorf ("invalid state to register signer: got %v, want PendingRegistration" , currentState )
301+ }
302+ err := k .espressoTEEVerifierCaller .RegisterService (k .dataPoster , k .state .attestation , k .state .data , uint8 (k .teeType ), k .serviceType )
227303 if err != nil {
228304 return err
229305 }
@@ -232,18 +308,18 @@ func (k *EspressoKeyManager) Register(getAttestationFunc func([]byte) ([]byte, e
232308 log .Info ("Register signer transaction sent" , "signer address" , signerAddr .Hex ())
233309
234310 // Verify our address is actually registered in contract
235- hasRegistered , err = k .VerifyRegistered ()
311+ hasRegistered , err : = k .VerifyRegistered ()
236312 if err != nil {
237313 return err
238314 }
239315 if ! hasRegistered {
240316 return errors .New ("address is not registered in contract even after successful transaction and retries" )
241317 }
242318
243- k . hasRegistered = true
244- if k . teeType == TESTS {
245- k . teeType = SGX
246- }
319+ // We are registered free up the memory
320+ k . state . currentState = Registered
321+ k . state . attestation = [] byte {}
322+ k . state . data = [] byte { }
247323 log .Info ("Signer registration confirmed on-chain" )
248324 return nil
249325}
@@ -265,15 +341,15 @@ func (k *EspressoKeyManager) SignMessage(message []byte) ([]byte, error) {
265341 return arbutil .SignMessage (message , k .privKey )
266342}
267343
268- func (k * EspressoKeyManager ) RegisterService () error {
344+ func (k * EspressoKeyManager ) Init () error {
269345 teeType := k .TeeType ()
270346 switch teeType {
271347 case SGX :
272- return k .Register (k .getAttestationQuote )
348+ return k .InitRegistration (k .getAttestationQuote )
273349 case NITRO :
274- return k .Register (k .getNitroAttestation )
350+ return k .InitRegistration (k .getNitroAttestation )
275351 case TESTS :
276- return k .Register (k .noOpSignerFunc )
352+ return k .InitRegistration (k .noOpSignerFunc )
277353 default :
278354 return fmt .Errorf ("unsupported tee Type: %d" , teeType )
279355 }
0 commit comments