How to optimize react-native-keychain performance? - performance

I am building a react-native application that uses react-native-keychain to securely save the user's tokens. I know that keychain is for saving username/password combination but i thought it would do no harm to save my tokens instead. I'm currently implementing some checking mechanisms that will check if there is a valid refresh token availavable (meaning that the last user didnt log out when leaving the app, as usually happens in mobile apps) and will act accordingly. This seems to be performing poorly (too slow) and i have come to the conclusion that it is the fetching of the token that is holding the app back (Keychain.getGenericPassword()).
The question is: Since keychain seems to be the safest way to store credentials localy, is there a way to optimise its performance or is there an equally safe but generaly faster alternative?

"react-native-keychain" version: "6.2.0"
For anyone still trying to resolve this issue. I had the same issue where the delay for me was about 10s or more. I was able to reduce it to less than a second after going through these two issues 1, 2. I followed the steps mentioned in this comment.
Use {storage: KeyChain.STORAGE_TYPE.AES} option when using the methods getGenericPassword and setGenericPassword
Goto this file: node_modules\react-native-keychain\android\src\main\java\com\oblador\keychain\KeychainModuleBuilder.java and set the DEFAULT_USE_WARM_UP to false.
Goto this file:
node_modules\react-native-keychain\android\src\main\java\com\oblador\keychain\KeychainModule.java
inside method getGenericPassword and change the following: Change
these lines
final String accessControl = getAccessControlOrDefault(options);
final boolean useBiometry = getUseBiometry(accessControl);
final CipherStorage current = getCipherStorageForCurrentAPILevel(useBiometry);
to
// final String accessControl = getAccessControlOrDefault(options);
// final boolean useBiometry = getUseBiometry(accessControl);
// final CipherStorage current = getCipherStorageForCurrentAPILevel(useBiometry);
final CipherStorage current = getSelectedStorage(options);
The issue seems to be because of a warming mechanism used with the RSA encryption. Please follow the above three links for further info.

Related

Yocto PREMIRROR/SOURCE_MIRROR_URL with url arguments (SAS_TOKEN) possible?

I sucessfully created a premirror for our yocto builds on an Azure Storage Blob,
that works if I set the access level to "Blob (Anonymous read).."
Now I wanted to keep the blob completely private, and access only via SAS Tokens.
SAS_TOKEN = "?sv=2019-12-12&ss=bf&srt=co&sp=rdl&se=2020-08-19T17:38:27Z&st=2020-08-19T09:38:27Z&spr=https&sig=abcdef_TEST"
INHERIT += "own-mirrors"
SOURCE_MIRROR_URL = "https://somewhere.blob.core.windows.net/our-mirror/downloads/BASENAME${SAS_TOKEN}"
BB_FETCH_PREMIRRORONLY = "1"
In general this works, but yocto (or to be exact the bitbake fetch module) will try then try to fetch from https://somewhere.blob.core.windows.net/our-mirror/downloads/bash-5.0.tar.gz%3Fsv%3D2019-12-12%26ss%3Dbf%26srt%3Dco%26sp%3Drdl%26se%3D2020-08-19T17%3A38%3A27Z%26st%3D2020-08-19T09%3A38%3A27Z%26spr%3Dhttps%26sig%3Dabcdef_TEST/bash-5.0.tar.gz
Which also encodes the special characters for the parameters and of course the fetch fill fail.
Did anybody has solved this or similar issues already?
Or is it possible to patch files inside the poky layer (namely in ./layers/poky/bitbake/lib/bb/fetch2) without changing them, so I can roll my on encodeurl function there?

How should I test if a PDU is too big in WinSNMP?

I am building an SNMP Agent for a Windows application using the Microsoft WinSNMP API. Currently everything is working for single-item get and set-request, and also for get-next to allow walking the defined tree (albeit with some caveats that are not relevant to this question).
I am now looking at multi-item get and also get-bulk.
My current procedure is to iterate through the list of requested items (the varbindlist within the PDU), treating each one individually, effectively causing an internal get. The result is added to the VBL, set into the PDU, and then sent back to the SNMP Manager, taking into account invalid requests, etc.
My question is how should I handle "too much" data (data that cannot fit into a single transport layer message)? Or more accurately, is there a way to test whether data is "too big" without actually attempting to transmit? The only way I can see in the API is to try sending, check the error, and try again.
In the case of a get-request this isn't a problem - if you can't return all of the requested data, you fail: so attempt sending, and if the error report is SNMPAPI_TL_PDU_TOO_BIG, send a default "error" PDU.
However, it is allowable for a response to bulk-get to return partial results.
The only way I can see to handle this is a tedious (?) loop of removing an item and trying again. Something similar to the following (some detail removed for brevity):
// Create an empty varbindlist
vbl = SnmpCreateVbl(session, NULL, NULL);
// Add all items to the list
SnmpSetVb(vbl, &oid, &value); // for each OID/Value pair
// Create the PDU
pdu = SnmpCreatePdu(session, SNMP_PDU_RESPONSE, ..., vbl);
bool retry;
do {
retry = false;
smiINT failed = SnmpSendMsg(session, ..., pdu);
if (failed && SNMPAPI_TL_PDU_TOO_BIG == SnmpGetLastError()) {
// too much data, delete the last vb
SnmpDeleteVb(vbl, SnmpCountVbl(vbl));
SnmpSetPduData(pdu, ..., vbl);
retry = true;
};
} while(retry);
This doesn't seem like an optimal approach - so is there another way that I've missed?
As a side-note, I know about libraries such as net-snmp, but my question is specific to the Microsoft API.
The RFC does require you to do what you pasted,
https://www.rfc-editor.org/rfc/rfc3416
Read page 16.
There does not seem to be a function exposed by WinSNMP API that can do this for you, so you have to write your own logic to handle it.

Security of private key when using "insecure" OpenSSL methods

I recently came across a situation where I absolutely needed to use the method OpenSSL::PKey::RSA#params. However, the doc says the following:
THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
...
Don’t use :-)) (It’s up to you)
What does this mean? How is the private key normally protected within the instance of the RSA key and how is this different from any regular object?
Can I prevent information from leaking by doing something like this, where the method is only accessed within a lambda:
private_key = OpenSSL::PKey::RSA.generate(2048)
save_private = lambda do
key = OpenSSL::Digest::SHA512.new.digest("password")
aes = OpenSSL::Cipher.new("AES-256-CFB")
iv = OpenSSL::Random.random_bytes(aes.iv_len)
aes.encrypt
aes.key, aes.iv = key, iv
aes.update(private_key.params.to_s) + aes.final
end
private_enc, save_private = save_private.call, nil
Also, if this security problem has anything to do with variables lingering in memory awaiting GC, can forcing garbage collection make things more secure?
GC.start
Thanks in advance to anybody who can clear this up.
It seems to give away information of the private key. The key components need to be available to perform any signing operation or decryption so normally the key information is in memory in the clear. Obviously if you retrieve it you must make sure that you keep it safe. I presume that this is where the warning comes in.
You can do all kinds of things like encrypting the private key parameters, but then you get to a point where you have to store the decryption key. Basically this will end up being impossible to solve without an external system (or a person keeping a password).

Make ZVAL persistent across the SAPI?

A ZVAL is typically created with emalloc so it is destroyed at the end of a page request. Is there a way to take an existing ZVAL and make it persist in the SAPI (equivalent of pemalloc)? What about creating a ZVAL with pemalloc?
Ideally what I'd like to do (in PHP code) is this:
class Object
{
public $foo;
}
if(!($object = persist("object")))
{
$object = persist("object", new Object());
}
$object->foo[] = "bar";
print count($object->foo);
On each request count would return +1 (assuming the same PHP "worker" is used every time - I'm using PHP-FPM).
You're basically describing http://lxr.php.net/opengrok/xref/PHP_5_3/ext/sysvshm/sysvshm.c#242
The closest you can get without duplicating functionality which is already in shm is https://github.com/flavius/php-persist. The catch: in a prefork/multiprocess SAPI (like apache's), different requests from the same client may end up in different processes, and as such, you'll see different data (try it on Linux + Firefox with a hard refresh every time in the browser).
Note: It's a work-in-progress, currently it persists only an integer. Adding an array should be trivial. Patches welcome. It still needs the deserialization part, and to actually use persist()'s first parameter.
zend_object can't be persisent therefore you can't do this. extensions like APC serializes the object into memory.

Loosing session between requests in Play 1.2.2

I'm having a really odd issue. I'm reusing a piece of code that was fully functional in a previous project but now fails. The code does something like this (code simplified to minimal failing scenario):
if (OpenID.isAuthenticationResponse()) {
UserInfo verifiedUser = OpenID.getVerifiedID();
String value = session.get(AppKeys.AUTH_METHOD); << ERROR
Application.index();
} else {
OpenID openid = getOpenId(client);
session.put(AppKeys.AUTH_METHOD, value);
if (!openid.verify()) {
Application.index();
}
}
Previously I could retrieve the value in the line marked as ERROR. Now that line sets value to null. I've done some tests and, somehow, the session values are lost during the requests although the session id is the same always (so the session in itself doesn't get lost).
I'm sure there is some configuration I've broken, but I'm not being able to find which one. Anyone knows?
In one of those situations of "find the answer just as you sent the question" I discovered the issue. This was the setting screwing the process:
# application.defaultCookieDomain=.xxxxx.com
As I'm in localhost the cookie was not retrieved, and in Play the session values are stored in the cookie as Play is stateless.
Yes, it's time to go to bed...

Resources