Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Keystore Provider and Keyhandle for Knox by Team Vulcans Limes (D) #9

Open
wants to merge 146 commits into
base: main
Choose a base branch
from

Conversation

noah-pe
Copy link

@noah-pe noah-pe commented Jun 3, 2024

  • Implemented provider.rs and key_handle.rs for Knox Vault
  • Implemented create_instance for KnoxProvider
  • Together with Team Netwatch (Android) we changed Box to Box
  • added Java Files for our Wrapper
  • added CreationError as a new SecurityModuleError

@noah-pe
Copy link
Author

noah-pe commented Jun 11, 2024

@ngussek ready for pull

IOException, NoSuchAlgorithmException, NoSuchProviderException,
InvalidAlgorithmParameterException, KeyStoreException {
String[] keyGenInfoArr = keyGenInfo.split(";");
String KEY_ALGORITHM = keyGenInfoArr[0];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are assuming that there will always be 4 entries available. If this is not true, then an exception will be thrown. If the exception is not caught, then the software will close, which can be seen as a denial-of-service. Please check that keyGenInfoArr contains at least 4 entries here. Also, if any value used to create keyGenInfo contained a ';' then injections would be possible. See https://owasp.org/Top10/A03_2021-Injection/

InvalidAlgorithmParameterException, KeyStoreException {
String[] keyGenInfoArr = keyGenInfo.split(";");
String KEY_ALGORITHM = keyGenInfoArr[0];
int KEY_SIZE = Integer.parseInt(keyGenInfoArr[1]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are assuming keyGenInfoArray[1],keyGenInfoArray[2] and keyGenInfoArray[3] contain data in the correct format. If this turns out not to be the case, then you'll end up with rather difficult problems to debug.

String PADDING = keyGenInfoArr[3];

KEY_NAME = key_id;
keyStore.load(null);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to load the keystore before storing the key inside of it, otherwise the keystore will throw an exception.
We set KEY_NAME = key_id, as we thought it will enhance readablillity, future-proofing and conformity.
Does this answer your question?

KeyStoreException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException,
NoSuchProviderException {

keyStore.load(null);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to load the keystore before using the needed key inside of it, if we dont the keystore will throw an exception.
Does this answer your question?

byte[] iv = cipher.getIV();
if (TRANSFORMATION.contains("/GCM/")) {
assert iv.length == 12; // GCM standard IV size is 12 Byte
} else if(TRANSFORMATION.contains("DESede")) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method description mentions GCM, CBC and CTR. Is DES support required?

byteBuffer.get(iv);
encryptedData = new byte[byteBuffer.remaining()];
byteBuffer.get(encryptedData);
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv); // 128 is the recommended TagSize

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor magic value into constant.

SecretKey secretKey = (SecretKey) key;
SecretKeyFactory factory = SecretKeyFactory.getInstance(secretKey.getAlgorithm(), ANDROID_KEY_STORE);
keyInfo = (KeyInfo) factory.getKeySpec(secretKey, KeyInfo.class);
keyPadding = keyInfo.getEncryptionPaddings()[0];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that paddings are actually available.

PrivateKey privateKey = (PrivateKey) key;
KeyFactory factory = KeyFactory.getInstance(privateKey.getAlgorithm(), ANDROID_KEY_STORE);
keyInfo = factory.getKeySpec(privateKey, KeyInfo.class);
keyPadding = keyInfo.getSignaturePaddings()[0];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that paddings are actually available.

} else {
throw new KeyStoreException("Unsupported key type");
}
return keyAlgorithm + "/" + keyInfo.getBlockModes()[0] + "/" + keyPadding;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that getBlockModes() contain at least one array entry.

InvalidKeySpecException {
KeyFactory keyFactory = KeyFactory.getInstance(privateKey.getAlgorithm(), ANDROID_KEY_STORE);
KeyInfo keyInfo = keyFactory.getKeySpec(privateKey, KeyInfo.class);
String hashAlgorithm = keyInfo.getDigests()[0].replaceAll("-", "");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that at least one digest exists.

Copy link

@studentfeedbackuser studentfeedbackuser Jun 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://security.snyk.io/package/npm/jquery/3.6.1

Although no vulnerabilities in file, as part of security best practise it would be best to update to latest version - if this (javadocs) will be deployed somewhere that external people can access, and if there is a sensible way to update javadoc dependencies without having to edit code (updating javadoc version perhaps). If updating javadoc does not help, then let's rather move for acceptance on this matter - no point in trying to hack an upgrade.

Copy link

@studentfeedbackuser studentfeedbackuser Jun 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something to think about: https://developer.android.com/training/articles/perf-jni

Quoting:
The JNIEnv is used for thread-local storage. For this reason, you cannot share a JNIEnv between threads. If a piece of code has no other way to get its JNIEnv, you should share the JavaVM, and use GetEnv to discover the thread's JNIEnv. (Assuming it has one; see AttachCurrentThread below.)

No code changes needed, but may be useful to mention this in a readme or doc.

noah-pe and others added 8 commits June 14, 2024 10:25
Changed the IV constants to be constants in the code and not magic numbers. Updated JavaDoc to include the special case of IVs when using 3DES with CBC.
Pentest feedback implemented, updated JavaDoc to fit current code.
generateKeyPair EC and RSA RegEx fixed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants