Get a Private Key using the specified storage strategy.
If storage is not specified, it uses the LocalDataStorage class.
Source
Future<PrivateKey> getPrivateKey({DataStorage storage}) async {
if (_cachedPrivateKey != null) {
return _cachedPrivateKey;
}
if (storage == null) {
storage = LocalDataStorage.INSTANCE;
}
String keyPath = "dsa_key:${window.location.pathname}";
String keyLockPath = "dsa_key_lock:${window.location.pathname}";
String randomToken = "${new DateTime.now().millisecondsSinceEpoch}"
" ${DSRandom.instance.nextUint16()}"
" ${DSRandom.instance.nextUint16()}";
bool hasKeyPath = false;
if (storage is SynchronousDataStorage) {
hasKeyPath = (storage as SynchronousDataStorage).hasSync(keyPath);
} else {
hasKeyPath = await storage.has(keyPath);
}
if (hasKeyPath) {
if (storage is SynchronousDataStorage) {
(storage as SynchronousDataStorage).storeSync(keyLockPath, randomToken);
} else {
await storage.store(keyLockPath, randomToken);
}
await new Future.delayed(const Duration(milliseconds: 20));
String existingToken;
String existingKey;
if (storage is SynchronousDataStorage) {
existingToken = (storage as SynchronousDataStorage).getSync(keyLockPath);
existingKey = (storage as SynchronousDataStorage).getSync(keyPath);
} else {
existingToken = await storage.get(keyLockPath);
existingKey = await storage.get(keyPath);
}
if (existingToken == randomToken) {
if (storage is LocalDataStorage) {
_startStorageLock(keyLockPath, randomToken);
}
_cachedPrivateKey = new PrivateKey.loadFromString(existingKey);
return _cachedPrivateKey;
} else {
// use temp key, don't lock it;
keyLockPath = null;
}
}
_cachedPrivateKey = await PrivateKey.generate();
if (keyLockPath != null) {
if (storage is SynchronousDataStorage) {
(storage as SynchronousDataStorage).storeSync(keyPath, _cachedPrivateKey.saveToString());
(storage as SynchronousDataStorage).storeSync(keyLockPath, randomToken);
} else {
await storage.store(keyPath, _cachedPrivateKey.saveToString());
await storage.store(keyLockPath, randomToken);
}
if (storage is LocalDataStorage) {
_startStorageLock(keyLockPath, randomToken);
}
}
return _cachedPrivateKey;
}