constructor()

in security/tpm/src/tpm.ts [52:185]


  constructor(registrationId?: string, customTpm?: any) {
    /*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_002: [The `customTpm` argument, if present` will be used at the underlying TPM provider.  Otherwise the TPM provider will the tss TPM client with a parameter of `false` for simulator use.] */
    this._tpm = customTpm ? customTpm : new Tpm(false);
    if (registrationId) {
      /*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_001: [The `registrationId` argument if present will be returned as the `registrationId` for subsequent calls to `getRegistrationId`.] */
      this._registrationId = registrationId;
    }
    this._fsm = new machina.Fsm({
      initialState: 'disconnected',
      states: {
        disconnected: {
          _onEnter: (callback, err) => {
            this._ek = null;
            this._srk = null;
            this._idKeyPub = null;
            if (callback) {
              if (err) {
                callback(err);
              } else {
                callback(null, null);
              }
            }
          },
          connect: (connectCallback) => this._fsm.transition('connecting', connectCallback),
          getEndorsementKey: (callback) => {
            this._fsm.handle('connect', (err, _result) => {
              if (err) {
                callback(err);
              } else {
                this._fsm.handle('getEndorsementKey', callback);
              }
            });
          },
          getStorageRootKey: (callback) => {
            this._fsm.handle('connect', (err, _result) => {
              if (err) {
                callback(err);
              } else {
                this._fsm.handle('getStorageRootKey', callback);
              }
            });
          },
          signWithIdentity: (dataToSign, callback) => {
            this._fsm.handle('connect', (err, _result) => {
              if (err) {
                callback(err);
              } else {
                this._fsm.handle('signWithIdentity', dataToSign, callback);
              }
            });
          },
          activateIdentityKey: (identityKey, callback) => {
            this._fsm.handle('connect', (err, _result) => {
              if (err) {
                callback(err);
              } else {
                this._fsm.handle('activateIdentityKey', identityKey, callback);
              }
            });
          }
        },
        connecting: {
          _onEnter: (callback) => {
            try {
              this._tpm.connect(() => {
                this._createPersistentPrimary('EK', tss.Endorsement, TpmSecurityClient._ekPersistentHandle, TpmSecurityClient._ekTemplate, (ekCreateErr: Error, ekPublicKey: TPMT_PUBLIC) => {
                  if (ekCreateErr) {
                    /*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_007: [Any errors from interacting with the TPM hardware will cause in SecurityDeviceError to be returned in the err parameter of the callback.] */
                    this._fsm.transition('disconnected', callback, ekCreateErr);
                  } else {
                    /*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_006: [The `getEndorsementKey` function shall query the TPM hardware and return the `endorsementKey` in the callback.] */
                    this._ek = ekPublicKey;
                    this._createPersistentPrimary('SRK', tss.Owner, TpmSecurityClient._srkPersistentHandle, TpmSecurityClient._srkTemplate, (srkCreateErr: Error, srkPublicKey: TPMT_PUBLIC) => {
                      if (srkCreateErr) {
                        /*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_009: [Any errors from interacting with the TPM hardware will cause in SecurityDeviceError to be returned in the err parameter of the callback.] */
                        this._fsm.transition('disconnected', callback, srkCreateErr);
                      } else {
                        /*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_008: [The `getStorageRootKey` function shall query the TPM hardware and return the `storageRootKey` in the callback.] */
                        this._srk = srkPublicKey;
                        this._readPersistentPrimary('IDENTITY', TpmSecurityClient._idKeyPersistentHandle, (_readIdErr: Error, idkPublicKey: TPMT_PUBLIC) => {
                          //
                          // Not any kind of fatal error if we can't retrieve the identity public portion.  This device might not have ever been provisioned.
                          // If there is a signing operation attempted before an activate is attempted, an error will occur.
                          //
                          this._idKeyPub = idkPublicKey;
                          this._fsm.transition('connected', callback);
                        });
                      }
                    });
                  }
                });
              });
            } catch (err) {
              this._fsm.transition('disconnected', callback, err);
            }
          },
          '*': () => this._fsm.deferUntilTransition()
        },
        connected: {
          _onEnter: (callback) => {
            callback(null);
          },
          getEndorsementKey: (callback) => {
            callback(null, this._ek.asTpm2B());
          },
          getStorageRootKey: (callback) => {
            callback(null, this._srk.asTpm2B());
          },
          signWithIdentity: (dataToSign, callback) => {
            this._signData(dataToSign, (err: Error, signedData: Buffer) => {
              if (err) {
                debug('Error from signing data: ' + err);
                this._fsm.transition('disconnected', callback, err);
              } else {
                callback(null, signedData);
              }
            });
          },
          activateIdentityKey: (identityKey, callback) => {
            this._activateIdentityKey(identityKey, (err: Error) => {
              if (err) {
                debug('Error from activate: ' + err);
                this._fsm.transition('disconnected', callback, err);
              } else {
                callback(null, null);
              }
            });
          },
        }
      }
    });
    this._fsm.on('transition', (data) => debug('TPM security State Machine: ' + data.fromState + ' -> ' + data.toState + ' (' + data.action + ')'));
    this._fsm.on('handling', (data) => debug('TPM security State Machine: handling ' + data.inputType));
  }