update dependencies, use common plugin

This commit is contained in:
2025-12-13 01:44:39 +01:00
parent e8999ae4e4
commit 498a5b5826
6 changed files with 58 additions and 83 deletions

View File

@@ -1,12 +1,11 @@
import com.infendro.plugin.infendro
import com.infendro.plugin.token
group = "com.infendro" group = "com.infendro"
version = "1.1.1" version = "1.1.1"
repositories {
maven("https://git.infendro.com/api/packages/Infendro/maven")
mavenCentral()
}
plugins { plugins {
alias(libs.plugins.infendro)
alias(libs.plugins.multiplatform) alias(libs.plugins.multiplatform)
id("maven-publish") id("maven-publish")
} }
@@ -18,9 +17,14 @@ kotlin {
} }
linuxX64() linuxX64()
repositories {
infendro()
mavenCentral()
}
sourceSets { sourceSets {
commonMain.dependencies { commonMain.dependencies {
implementation(libs.random) implementation(libs.prng)
implementation(libs.mac) implementation(libs.mac)
implementation(libs.hash) implementation(libs.hash)
implementation(libs.bytearray) implementation(libs.bytearray)
@@ -28,35 +32,11 @@ kotlin {
} }
compilerOptions { compilerOptions {
freeCompilerArgs.add("-opt-in=kotlin.ExperimentalUnsignedTypes")
freeCompilerArgs.add("-opt-in=kotlin.time.ExperimentalTime") freeCompilerArgs.add("-opt-in=kotlin.time.ExperimentalTime")
} }
} }
publishing { publishing.repositories {
repositories { infendro(token)
maven {
url = uri("https://git.infendro.com/api/packages/Infendro/maven")
authentication.create("header", HttpHeaderAuthentication::class)
credentials(HttpHeaderCredentials::class) {
val token = secret("git.token") ?: throw GradleException()
name = "Authorization"
value = "token $token"
}
}
}
}
fun secret(
key: String,
): String? {
val property = key
val environment = key
.uppercase()
.replace(".", "__")
val prop = properties[property] as String?
val env = System.getenv(environment)
return prop ?: env
} }

View File

@@ -1,15 +1,17 @@
[versions] [versions]
kotlin = "2.1.20" infendro = "1.0.0"
random = "1.0.0" kotlin = "2.2.21"
mac = "1.1.2" prng = "1.2.0"
hash = "1.2.2" mac = "1.2.0"
bytearray = "1.1.1" hash = "1.3.2"
bytearray = "1.2.4"
[plugins] [plugins]
infendro = { id = "com.infendro.plugin", version.ref = "infendro" }
multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
[libraries] [libraries]
random = { module = "com.infendro:random", version.ref = "random" } prng = { module = "com.infendro:prng", version.ref = "prng" }
mac = { module = "com.infendro:mac", version.ref = "mac" } mac = { module = "com.infendro:mac", version.ref = "mac" }
hash = { module = "com.infendro:hash", version.ref = "hash" } hash = { module = "com.infendro:hash", version.ref = "hash" }
bytearray = { module = "com.infendro:bytearray", version.ref = "bytearray" } bytearray = { module = "com.infendro:bytearray", version.ref = "bytearray" }

View File

@@ -1 +1,6 @@
rootProject.name = "otp" rootProject.name = "otp"
pluginManagement.repositories {
maven("https://git.infendro.com/api/packages/Infendro/maven")
mavenCentral()
}

View File

@@ -1,19 +1,20 @@
package com.infendro.otp package com.infendro.otp
import com.infendro.bytearray.toByteArray
import com.infendro.bytearray.toInt import com.infendro.bytearray.toInt
import com.infendro.bytearray.toUByteArray
import com.infendro.hash.HashFunction import com.infendro.hash.HashFunction
import com.infendro.hash.SHA1 import com.infendro.hash.sha1.SHA1
import com.infendro.mac.HMAC import com.infendro.mac.HMAC
import kotlin.experimental.and
import kotlin.math.pow import kotlin.math.pow
class HOTP( class HOTP(
val function: HashFunction = SHA1, val function: HashFunction = SHA1,
val length: Int = 6, val length: Int = 6,
) { ) {
private val hmac = HMAC(function)
fun verify( fun verify(
secret: ByteArray, secret: UByteArray,
counter: Long, counter: Long,
otp: String, otp: String,
): Boolean { ): Boolean {
@@ -21,33 +22,31 @@ class HOTP(
} }
fun generate( fun generate(
secret: ByteArray, secret: UByteArray,
counter: Long, counter: Long,
): String { ): String {
if (counter < 0) throw Exception() if (counter < 0)
throw IllegalArgumentException()
val hash = generateHash( val hash = generateHash(secret, counter.toUByteArray())
secret,
counter.toByteArray()
)
return otp(hash) return otp(hash)
} }
private fun generateHash( private fun generateHash(
secret: ByteArray, secret: UByteArray,
value: ByteArray, value: UByteArray,
): ByteArray { ): UByteArray {
return HMAC(function).hash(secret, value) return hmac.hash(secret, value)
} }
private fun otp( private fun otp(
hash: ByteArray, hash: UByteArray,
): String { ): String {
val offset = (hash.last() and 0xF).toInt() val offset = (hash.last() and 0xFU).toInt()
var truncatedHash = hash var truncatedHash = hash
.drop(offset) .drop(offset).take(4)
.take(4) .toUByteArray()
.toInt() and 0x7FFFFFFF .toInt() and 0x7FFFFFFF
truncatedHash %= 10.0.pow(length).toInt() truncatedHash %= 10.0.pow(length).toInt()

View File

@@ -1,22 +1,14 @@
package com.infendro.otp package com.infendro.otp
import com.infendro.hash.* import com.infendro.hash.HashFunction
import com.infendro.random.PRNG import com.infendro.random.csprng.CSPRNG
object SecretGenerator { class SecretGenerator(
private val random = PRNG.HMAC val function: HashFunction,
) {
private val random = CSPRNG.HMAC(function)
fun generate( fun generate(): ByteArray {
algorithm: HashFunction = SHA1, return random.nextBytes(function.bytes)
): ByteArray {
val bytes = when (algorithm) {
MD5 -> 16
SHA1 -> 20
SHA224 -> 28
SHA256 -> 32
SHA384 -> 48
SHA512 -> 64
}
return random.nextBytes(bytes)
} }
} }

View File

@@ -1,20 +1,20 @@
package com.infendro.otp package com.infendro.otp
import com.infendro.hash.HashFunction import com.infendro.hash.HashFunction
import com.infendro.hash.SHA1 import com.infendro.hash.sha1.SHA1
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
import kotlin.time.Instant import kotlin.time.Instant
class TOTP( class TOTP(
function: HashFunction = SHA1, val function: HashFunction = SHA1,
length: Int = 6, val length: Int = 6,
val period: Duration = 30.seconds, val period: Duration = 30.seconds,
) { ) {
val hotp = HOTP(function, length) private val hotp = HOTP(function, length)
fun verify( fun verify(
secret: ByteArray, secret: UByteArray,
instant: Instant, instant: Instant,
otp: String, otp: String,
): Boolean { ): Boolean {
@@ -22,13 +22,10 @@ class TOTP(
} }
fun generate( fun generate(
secret: ByteArray, secret: UByteArray,
instant: Instant, instant: Instant,
): String { ): String {
return hotp.generate( return hotp.generate(secret, counter(instant))
secret,
counter(instant)
)
} }
private fun counter( private fun counter(