in security/tpm/src/tpm.ts [419:573]
private _activateIdentityKey(activationBlob: Buffer, activateCallback: (err: Error) => void): void {
//
// Un-marshal components of the activation blob received from the provisioning service.
//
const buf: tss.TpmBuffer = activationBlob instanceof Buffer ? new tss.TpmBuffer(activationBlob) : activationBlob;
const credentialBlob: tss.TPMS_ID_OBJECT = buf.createSizedObj(tss.TPMS_ID_OBJECT);
const encodedSecret: tss.TPM2B_ENCRYPTED_SECRET = buf.createObj(tss.TPM2B_ENCRYPTED_SECRET);
const idKeyDupBlob: tss.TPM2B_PRIVATE = buf.createObj(tss.TPM2B_PRIVATE);
const encWrapKey: tss.TPM2B_ENCRYPTED_SECRET = buf.createObj(tss.TPM2B_ENCRYPTED_SECRET);
this._idKeyPub = buf.createSizedObj(TPMT_PUBLIC);
this._encUriData = buf.createObj(tss.TPM2B_DATA);
debug('The value of the encUriData: ' + this._encUriData.toString());
if (!buf.isOk())
return activateCallback(new errors.SecurityDeviceError('Could not unmarshal activation data'));
if (buf.curPos !== buf.size)
debug('WARNING: Activation Blob sent by DPS has contains extra unidentified data');
//
// Start a policy session to be used with ActivateCredential()
//
this._tpm.GetRandom(TpmSecurityClient._tpmNonceSize, (err: tss.TpmError, nonce: Buffer) => {
if (err) {
const secErr = new errors.SecurityDeviceError('Could not get random nonce');
(<any>secErr).tpmError = err;
activateCallback(secErr);
} else {
this._tpm.StartAuthSession(null, null, nonce, null, tss.TPM_SE.POLICY, tss.NullSymDef, TPM_ALG_ID.SHA256, (err: tss.TpmError, resp: tss.StartAuthSessionResponse) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
debug('StartAuthSession(POLICY_SESS) returned ' + TPM_RC[rc] + '; sess handle: ' + resp.handle.handle.toString(16));
if (rc !== TPM_RC.SUCCESS) {
/*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_016: [If an error is encountered activating the identity key, the callback with be invoked with an `Error` of `SecurityDeviceError`.] */
activateCallback(new errors.SecurityDeviceError('Authorization session unable to be created. RC value: ' + TPM_RC[rc].toString()));
} else {
const policySession = new tss.Session(resp.handle, resp.nonceTPM);
//
// Apply the policy necessary to authorize an EK on Windows
//
// this._tpm.withSession(tss.NullPwSession).PolicySecret(tss.Endorsement, policySession.SessIn.sessionHandle, null, null, null, 0, (err: tss.TpmError, _resp: tss.PolicySecretResponse) => {
this._tpm.PolicySecret(tss.Endorsement, policySession.SessIn.sessionHandle, null, null, null, 0, (err: tss.TpmError, _resp: tss.PolicySecretResponse) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
debug('PolicySecret() returned ' + TPM_RC[rc]);
if (rc !== TPM_RC.SUCCESS) {
/*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_016: [If an error is encountered activating the identity key, the callback with be invoked with an `Error` of `SecurityDeviceError`.] */
activateCallback(new errors.SecurityDeviceError('Unable to apply the necessary policy to authorize the EK. RC value: ' + TPM_RC[rc].toString()));
} else {
//
// Use ActivateCredential() to decrypt symmetric key that is used as an inner protector
// of the duplication blob of the new Device ID key generated by DRS.
//
this._tpm.withSessions(tss.NullPwSession, policySession).ActivateCredential(TpmSecurityClient._srkPersistentHandle, TpmSecurityClient._ekPersistentHandle, credentialBlob, encodedSecret.secret, (err: tss.TpmError, innerWrapKey: Buffer) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
debug('ActivateCredential() returned ' + TPM_RC[rc] + '; innerWrapKey size ' + innerWrapKey.length);
if (rc !== TPM_RC.SUCCESS) {
/*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_016: [If an error is encountered activating the identity key, the callback with be invoked with an `Error` of `SecurityDeviceError`.] */
activateCallback(new errors.SecurityDeviceError('Unable to decrypt the symmetric key used to protect duplication blob. RC value: ' + TPM_RC[rc].toString()));
} else if (innerWrapKey.length === 0) {
activateCallback(new errors.SecurityDeviceError('Unable to unwrap inner key - must have administrator privilege'));
} else {
//
// Initialize parameters of the symmetric key used by DRS
// Note that the client uses the key size chosen by DRS, but other parameters are fixed (an AES key in CFB mode).
//
const symDef = new tss.TPMT_SYM_DEF_OBJECT(TPM_ALG_ID.AES, innerWrapKey.length * 8, TPM_ALG_ID.CFB); //DevSkim: ignore DS187371
//
// Import the new Device ID key issued by DRS to the device's TPM
//
this._tpm.withSession(tss.NullPwSession).Import(TpmSecurityClient._srkPersistentHandle, innerWrapKey, this._idKeyPub, idKeyDupBlob, encWrapKey.secret, symDef, (err: tss.TpmError, idKeyPrivate: TPM2B_PRIVATE) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
debug('Import() returned ' + TPM_RC[rc] + '; idKeyPrivate size ' + idKeyPrivate.buffer.length);
if (rc !== TPM_RC.SUCCESS) {
/*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_016: [If an error is encountered activating the identity key, the callback with be invoked with an `Error` of `SecurityDeviceError`.] */
activateCallback(new errors.SecurityDeviceError('Unable to import the device id key into the TPM. RC value: ' + TPM_RC[rc].toString()));
} else {
//
// Load the imported key into the TPM
//
this._tpm.withSession(tss.NullPwSession).Load(TpmSecurityClient._srkPersistentHandle, idKeyPrivate, this._idKeyPub, (err: tss.TpmError, hIdKey: TPM_HANDLE) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
debug('Load() returned ' + TPM_RC[rc] + '; ID key handle: 0x' + hIdKey.handle.toString(16));
if (rc !== TPM_RC.SUCCESS) {
/*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_016: [If an error is encountered activating the identity key, the callback with be invoked with an `Error` of `SecurityDeviceError`.] */
activateCallback(new errors.SecurityDeviceError('Unable to load the device id key into the TPM. RC value: ' + TPM_RC[rc].toString()));
} else {
//
// Remove possibly existing persistent instance of the previous Device ID key
//
this._tpm.allowErrors().withSession(tss.NullPwSession).EvictControl(tss.Owner, TpmSecurityClient._idKeyPersistentHandle, TpmSecurityClient._idKeyPersistentHandle, () => {
//
// Persist the new Device ID key
//
this._tpm.withSession(tss.NullPwSession).EvictControl(tss.Owner, hIdKey, TpmSecurityClient._idKeyPersistentHandle, (err: tss.TpmError) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
if (rc !== TPM_RC.SUCCESS) {
/*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_016: [If an error is encountered activating the identity key, the callback with be invoked with an `Error` of `SecurityDeviceError`.] */
activateCallback(new errors.SecurityDeviceError('Unable to persist the device id key into the TPM. RC value: ' + TPM_RC[rc].toString()));
} else {
//
// Free the ID Key transient handle and the session object. Doesn't matter if it "fails". Go on at this point./
//
this._tpm.FlushContext(hIdKey, (err: tss.TpmError) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
debug('FlushContext(TRANS_ID_KEY) returned ' + TPM_RC[rc]);
if (err) {
const secErr = new errors.SecurityDeviceError('Could not get TPM capabilities');
(<any>secErr).tpmError = err;
activateCallback(secErr);
} else {
this._tpm.FlushContext(policySession.SessIn.sessionHandle, (err: tss.TpmError) => {
debug('FlushContext(POLICY_SESS) returned ' + TPM_RC[rc]);
if (err) {
const secErr = new errors.SecurityDeviceError('Could not get TPM capabilities');
(<any>secErr).tpmError = err;
activateCallback(secErr);
} else {
activateCallback(null);
}
});
}
});
}
});
});
}
});
}
});
}
});
}
});
}
});
}
});
}