mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
CredentialAttributes.kt — cleanup and improve docs
This commit is contained in:
@@ -230,4 +230,6 @@ fun createKeePassStore(dbFile: Path, masterPasswordFile: Path): PasswordSafe {
|
||||
keepassDb = store.dbFile.toString()
|
||||
})
|
||||
return BasePasswordSafe(settings, store)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CredentialAttributes.toPasswordStoreable() = if (isPasswordMemoryOnly) CredentialAttributes(serviceName, userName, requestor) else this
|
||||
@@ -2,24 +2,20 @@
|
||||
package com.intellij.credentialStore
|
||||
|
||||
import com.intellij.ide.passwordSafe.PasswordSafe
|
||||
import com.intellij.util.ArrayUtil
|
||||
import com.intellij.util.text.nullize
|
||||
import org.jetbrains.annotations.Contract
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.CharBuffer
|
||||
import java.nio.charset.CodingErrorAction
|
||||
|
||||
const val SERVICE_NAME_PREFIX = "IntelliJ Platform"
|
||||
|
||||
fun generateServiceName(subsystem: String, key: String) = "$SERVICE_NAME_PREFIX $subsystem — $key"
|
||||
|
||||
/**
|
||||
* requestor is deprecated. Never use it in new code.
|
||||
* Consider using [generateServiceName] to generate [serviceName].
|
||||
*
|
||||
* [requestor] is deprecated (never use it in a new code).
|
||||
*/
|
||||
data class CredentialAttributes @JvmOverloads constructor(val serviceName: String, val userName: String? = null, val requestor: Class<*>? = null, val isPasswordMemoryOnly: Boolean = false)
|
||||
|
||||
fun CredentialAttributes.toPasswordStoreable() = if (isPasswordMemoryOnly) CredentialAttributes(serviceName, userName, requestor) else this
|
||||
|
||||
// user cannot be empty, but password can be
|
||||
class Credentials(user: String?, val password: OneTimeString? = null) {
|
||||
constructor(user: String?, password: String?) : this(user, password?.let(::OneTimeString))
|
||||
@@ -28,7 +24,7 @@ class Credentials(user: String?, val password: OneTimeString? = null) {
|
||||
|
||||
constructor(user: String?, password: ByteArray?) : this(user, password?.let { OneTimeString(password) })
|
||||
|
||||
val userName: String? = user.nullize()
|
||||
val userName = user.nullize()
|
||||
|
||||
fun getPasswordAsString() = password?.toString()
|
||||
|
||||
@@ -44,7 +40,7 @@ class Credentials(user: String?, val password: OneTimeString? = null) {
|
||||
|
||||
@Suppress("FunctionName", "DeprecatedCallableAddReplaceWith")
|
||||
/**
|
||||
* DEPRECATED. Never use it in a new code.
|
||||
* @deprecated Never use it in a new code.
|
||||
*/
|
||||
@Deprecated("Never use it in a new code.")
|
||||
fun CredentialAttributes(requestor: Class<*>, userName: String?) = CredentialAttributes(requestor.name, userName, requestor)
|
||||
@@ -71,29 +67,4 @@ fun getAndMigrateCredentials(oldAttributes: CredentialAttributes, newAttributes:
|
||||
}
|
||||
}
|
||||
return credentials
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
@JvmOverloads
|
||||
fun OneTimeString(value: ByteArray, offset: Int = 0, length: Int = value.size - offset, clearable: Boolean = false): OneTimeString {
|
||||
if (length == 0) {
|
||||
return OneTimeString(ArrayUtil.EMPTY_CHAR_ARRAY)
|
||||
}
|
||||
|
||||
// jdk decodes to heap array, but since this code is very critical, we cannot rely on it, so, we don't use Charsets.UTF_8.decode()
|
||||
val charsetDecoder = Charsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE)
|
||||
val charArray = CharArray((value.size * charsetDecoder.maxCharsPerByte().toDouble()).toInt())
|
||||
charsetDecoder.reset()
|
||||
val charBuffer = CharBuffer.wrap(charArray)
|
||||
var cr = charsetDecoder.decode(ByteBuffer.wrap(value, offset, length), charBuffer, true)
|
||||
if (!cr.isUnderflow) {
|
||||
cr.throwException()
|
||||
}
|
||||
cr = charsetDecoder.flush(charBuffer)
|
||||
if (!cr.isUnderflow) {
|
||||
cr.throwException()
|
||||
}
|
||||
|
||||
value.fill(0, offset, offset + length)
|
||||
return OneTimeString(charArray, 0, charBuffer.position(), clearable = clearable)
|
||||
}
|
||||
@@ -2,10 +2,13 @@
|
||||
package com.intellij.credentialStore
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.util.ArrayUtil
|
||||
import com.intellij.util.ExceptionUtil
|
||||
import com.intellij.util.io.toByteArray
|
||||
import com.intellij.util.text.CharArrayCharSequence
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.CharBuffer
|
||||
import java.nio.charset.CodingErrorAction
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
/**
|
||||
@@ -89,4 +92,29 @@ class OneTimeString @JvmOverloads constructor(value: CharArray, offset: Int = 0,
|
||||
consume(false)
|
||||
builder.append(myChars, myStart, length)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
@JvmOverloads
|
||||
fun OneTimeString(value: ByteArray, offset: Int = 0, length: Int = value.size - offset, clearable: Boolean = false): OneTimeString {
|
||||
if (length == 0) {
|
||||
return OneTimeString(ArrayUtil.EMPTY_CHAR_ARRAY)
|
||||
}
|
||||
|
||||
// jdk decodes to heap array, but since this code is very critical, we cannot rely on it, so, we don't use Charsets.UTF_8.decode()
|
||||
val charsetDecoder = Charsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE)
|
||||
val charArray = CharArray((value.size * charsetDecoder.maxCharsPerByte().toDouble()).toInt())
|
||||
charsetDecoder.reset()
|
||||
val charBuffer = CharBuffer.wrap(charArray)
|
||||
var cr = charsetDecoder.decode(ByteBuffer.wrap(value, offset, length), charBuffer, true)
|
||||
if (!cr.isUnderflow) {
|
||||
cr.throwException()
|
||||
}
|
||||
cr = charsetDecoder.flush(charBuffer)
|
||||
if (!cr.isUnderflow) {
|
||||
cr.throwException()
|
||||
}
|
||||
|
||||
value.fill(0, offset, offset + length)
|
||||
return OneTimeString(charArray, 0, charBuffer.position(), clearable = clearable)
|
||||
}
|
||||
+2
-32
@@ -2,8 +2,8 @@
|
||||
package com.intellij.ide.passwordSafe.impl.providers;
|
||||
|
||||
import com.intellij.credentialStore.CredentialAttributes;
|
||||
import com.intellij.credentialStore.CredentialAttributesKt;
|
||||
import com.intellij.credentialStore.OneTimeString;
|
||||
import com.intellij.credentialStore.OneTimeStringKt;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -81,17 +81,6 @@ public class EncryptionUtil {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate key based on password
|
||||
*
|
||||
* @param password the password to use
|
||||
* @return the generated key
|
||||
*/
|
||||
public static byte[] genPasswordKey(@NotNull String password) {
|
||||
return genKey(hash(getUTF8Bytes(password)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encrypt key (does not use salting, so the encryption result is the same for the same input)
|
||||
*
|
||||
@@ -111,25 +100,6 @@ public class EncryptionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt key (does not use salting, so the encryption result is the same for the same input)
|
||||
*
|
||||
* @param password the secret key to use
|
||||
* @param encryptedKey the key to decrypt
|
||||
* @return the decrypted key
|
||||
*/
|
||||
public static byte[] decryptKey(byte[] password, byte[] encryptedKey) {
|
||||
try {
|
||||
Cipher c = Cipher.getInstance(ENCRYPT_KEY_ALGORITHM);
|
||||
c.init(Cipher.DECRYPT_MODE, new SecretKeySpec(password, SECRET_KEY_ALGORITHM), CBC_SALT_KEY);
|
||||
return c.doFinal(encryptedKey);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(ENCRYPT_KEY_ALGORITHM + " is not available", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encrypt key (does not use salting, so the encryption result is the same for the same input)
|
||||
*
|
||||
@@ -179,7 +149,7 @@ public class EncryptionUtil {
|
||||
if (len < 0 || len > plain.length - 4) {
|
||||
throw new IllegalStateException("Unmatched password is used");
|
||||
}
|
||||
return CredentialAttributesKt.OneTimeString(plain, 4, len);
|
||||
return OneTimeStringKt.OneTimeString(plain, 4, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user