All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.radarbase.auth.jwks.JwkAlgorithmParser.kt Maven / Gradle / Ivy

package org.radarbase.auth.jwks

import com.auth0.jwt.algorithms.Algorithm
import org.radarbase.auth.exception.InvalidPublicKeyException
import org.radarbase.auth.exception.TokenValidationException
import org.radarbase.auth.jwks.JsonWebKey.Companion.ALGORITHM_EC
import org.radarbase.auth.jwks.JsonWebKey.Companion.ALGORITHM_RSA
import java.math.BigInteger
import java.security.AlgorithmParameters
import java.security.GeneralSecurityException
import java.security.KeyFactory
import java.security.NoSuchAlgorithmException
import java.security.interfaces.ECPublicKey
import java.security.interfaces.RSAPublicKey
import java.security.spec.*
import java.util.*

class JwkAlgorithmParser(
    private val supportedAlgorithmsForWebKeySets: List,
) : JwkParser {

    constructor() : this(listOf(ECPEMCertificateParser(), RSAPEMCertificateParser()))

    override fun parse(key: JsonWebKey): Algorithm {
        if (key.x5c.isNotEmpty()) {
            val x5cAlgorithm = supportedAlgorithmsForWebKeySets
                .firstNotNullOfOrNull { parser ->
                    try {
                        parser.parseAlgorithm(key.x5c[0])
                    } catch (ex: Exception) {
                        null
                    }
                }
            if (x5cAlgorithm != null) return x5cAlgorithm
        }

        return when (key) {
            is MPJsonWebKey -> supportedAlgorithmsForWebKeySets
                .firstOrNull { algorithm -> key.value.startsWith(algorithm.keyHeader) }
                ?.parseAlgorithm(key.value)
                ?: throw TokenValidationException("Unsupported public key: $key")
            is RSAJsonWebKey -> try {
                val keyFactory: KeyFactory = KeyFactory.getInstance(ALGORITHM_RSA)
                val publicKeySpec = RSAPublicKeySpec(
                    BigInteger(1, Base64.getUrlDecoder().decode(key.n)),
                    BigInteger(1, Base64.getUrlDecoder().decode(key.e))
                )
                (keyFactory.generatePublic(publicKeySpec) as RSAPublicKey)
                    .toAlgorithm(hashSize = key.keySize())
            } catch (e: GeneralSecurityException) {
                throw InvalidPublicKeyException("Invalid public key", e)
            }
            is ECDSAJsonWebKey -> try {
                val keyFactory = KeyFactory.getInstance(ALGORITHM_EC)
                val keySize = key.curve()
                val ecPublicKeySpec = ECPublicKeySpec(
                    ECPoint(
                        BigInteger(1, Base64.getUrlDecoder().decode(key.x)),
                        BigInteger(1, Base64.getUrlDecoder().decode(key.y))
                    ),
                    AlgorithmParameters.getInstance(ALGORITHM_EC).run {
                        init(ECGenParameterSpec(keySize.ecStdName))
                        getParameterSpec(ECParameterSpec::class.java)
                    }
                )
                (keyFactory.generatePublic(ecPublicKeySpec) as ECPublicKey)
                    .toAlgorithm(keySize = key.curve())
            } catch (e: NoSuchAlgorithmException) {
                throw InvalidPublicKeyException("Invalid algorithm to generate key", e)
            } catch (e: GeneralSecurityException) {
                throw InvalidPublicKeyException("Invalid public key", e)
            }
        }
    }

    override fun toString(): String = buildString(50) {
        append("JwkAlgorithmParser')
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy