From 38ae14cc4d23bf2d255bac0427ab4c2a0d827a21 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Mon, 3 Dec 2018 14:09:42 -0800 Subject: [PATCH] Use UTF8 for Azure token cache (#3391) * Switch token cache encryption encoding to UTF8 * Try to parse as binary in fallback * Code review feedback --- .../src/account-provider/tokenCache.ts | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/extensions/azurecore/src/account-provider/tokenCache.ts b/extensions/azurecore/src/account-provider/tokenCache.ts index 8578504e3a..96e3bf4d4e 100644 --- a/extensions/azurecore/src/account-provider/tokenCache.ts +++ b/extensions/azurecore/src/account-provider/tokenCache.ts @@ -223,22 +223,16 @@ export default class TokenCache implements adal.TokenCache { return this.getOrCreateEncryptionParams() .then(encryptionParams => { try { - let cacheCipher = fs.readFileSync(self._cacheSerializationPath, TokenCache.FsOptions); - - let decipher = crypto.createDecipheriv(TokenCache.CipherAlgorithm, encryptionParams.key, encryptionParams.initializationVector); - let cacheJson = decipher.update(cacheCipher, 'hex', 'binary'); - cacheJson += decipher.final('binary'); - - // Deserialize the JSON into the array of tokens - let cacheObj = JSON.parse(cacheJson); - for (let objIndex in cacheObj) { - // Rehydrate Date objects since they will always serialize as a string - cacheObj[objIndex].expiresOn = new Date(cacheObj[objIndex].expiresOn); - } - - return cacheObj; + return self.decryptCache('utf8', encryptionParams); } catch (e) { - throw e; + try { + // try to parse using 'binary' encoding and rewrite cache as UTF8 + let response = self.decryptCache('binary', encryptionParams); + self.writeCache(response); + return response; + } catch (e) { + throw e; + } } }) .then(null, err => { @@ -248,6 +242,22 @@ export default class TokenCache implements adal.TokenCache { }); } + private decryptCache(encoding: crypto.Utf8AsciiBinaryEncoding, encryptionParams: EncryptionParams): adal.TokenResponse[] { + let cacheCipher = fs.readFileSync(this._cacheSerializationPath, TokenCache.FsOptions); + let decipher = crypto.createDecipheriv(TokenCache.CipherAlgorithm, encryptionParams.key, encryptionParams.initializationVector); + let cacheJson = decipher.update(cacheCipher, 'hex', encoding); + cacheJson += decipher.final(encoding); + + // Deserialize the JSON into the array of tokens + let cacheObj = JSON.parse(cacheJson); + for (let objIndex in cacheObj) { + // Rehydrate Date objects since they will always serialize as a string + cacheObj[objIndex].expiresOn = new Date(cacheObj[objIndex].expiresOn); + } + + return cacheObj; + } + private removeFromCache(cache: adal.TokenResponse[], entries: adal.TokenResponse[]): adal.TokenResponse[] { entries.forEach((entry: adal.TokenResponse) => { // Check to see if the entry exists @@ -274,7 +284,7 @@ export default class TokenCache implements adal.TokenCache { let cacheJson = JSON.stringify(cache); let cipher = crypto.createCipheriv(TokenCache.CipherAlgorithm, encryptionParams.key, encryptionParams.initializationVector); - let cacheCipher = cipher.update(cacheJson, 'binary', 'hex'); + let cacheCipher = cipher.update(cacheJson, 'utf8', 'hex'); cacheCipher += cipher.final('hex'); fs.writeFileSync(self._cacheSerializationPath, cacheCipher, TokenCache.FsOptions);