Skip to content

Commit

Permalink
CryptoPublicKey.Rsa -> CryptoPublicKey.RSA
Browse files Browse the repository at this point in the history
  • Loading branch information
JesusMcCloud committed Sep 26, 2024
1 parent 7ca2a4a commit 8d66a7e
Show file tree
Hide file tree
Showing 23 changed files with 64 additions and 70 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

* Move `Attestation` from Supreme to Indispensable
* Rename `parse()` to `deserialize()` in `JwsSigned` and `JweEncrypted` to align with COSE
* Rename `CryptoPublicKey.Rsa` -> `CryptoPublicKey.RSA` for consistency reasons

## 3.0

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ when (val pk = cert.publicKey) {
} contains an EC public key using curve ${pk.curve}"
)

is CryptoPublicKey.Rsa -> println(
is CryptoPublicKey.RSA -> println(
"Certificate with serial no. ${
cert.tbsCertificate.serialNumber
} contains a ${pk.bits.number} bit RSA public key"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ fun CryptoPublicKey.toCoseKey(algorithm: CoseAlgorithm? = null, keyId: ByteArray
}
}

is CryptoPublicKey.Rsa ->
is CryptoPublicKey.RSA ->
if ((algorithm != null) && (algorithm !in listOf(
CoseAlgorithm.PS256,
CoseAlgorithm.PS384,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ sealed class CoseKeyParams : SpecializedCryptoPublicKey {
}

override fun toCryptoPublicKey(): KmmResult<CryptoPublicKey> = catching {
CryptoPublicKey.Rsa(
CryptoPublicKey.RSA(
n = n ?: throw IllegalArgumentException("Missing modulus n"),
e = Int.decodeFromAsn1ContentBytes(e ?:
throw IllegalArgumentException("Missing or invalid exponent e"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ data class JsonWebKey(
}

JwkType.RSA -> {
CryptoPublicKey.Rsa(
CryptoPublicKey.RSA(
n = n ?: throw IllegalArgumentException("Missing modulus n"),
e = e?.let { bytes -> Int.decodeFromAsn1ContentBytes(bytes) }
?: throw IllegalArgumentException("Missing or invalid exponent e")
Expand Down Expand Up @@ -358,7 +358,7 @@ fun CryptoPublicKey.toJsonWebKey(keyId: String? = this.jwkId): JsonWebKey =
)


is CryptoPublicKey.Rsa ->
is CryptoPublicKey.RSA ->
JsonWebKey(
type = JwkType.RSA,
keyId = keyId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class JsonWebKeyJvmTest : FreeSpec({
"JWK can be created from n and e" - {
val nFromBc = (keyPairRSA.public as RSAPublicKey).modulus.toByteArray()
val eFromBc = (keyPairRSA.public as RSAPublicKey).publicExponent.toInt()
val pubKey = CryptoPublicKey.Rsa(nFromBc, eFromBc).also { it.jwkId = it.didEncoded }
val pubKey = CryptoPublicKey.RSA(nFromBc, eFromBc).also { it.jwkId = it.didEncoded }
val jwk = pubKey.toJsonWebKey()

jwk.shouldNotBeNull()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ sealed class CryptoPublicKey : Asn1Encodable<Asn1Sequence>, Identifiable {
+BitString(iosEncoded)
}

is Rsa -> {
is RSA -> {
Asn1.Sequence {
+Asn1.Sequence {
+oid
Expand Down Expand Up @@ -97,7 +97,7 @@ sealed class CryptoPublicKey : Asn1Encodable<Asn1Sequence>, Identifiable {
EC.fromAnsiX963Bytes(ECCurve.SECP_521_R_1, keyBytes)

0x1205uL ->
Rsa.fromPKCS1encoded(keyBytes)
RSA.fromPKCS1encoded(keyBytes)

else ->
throw IllegalArgumentException("Unknown public key identifier $codec")
Expand Down Expand Up @@ -126,14 +126,14 @@ sealed class CryptoPublicKey : Asn1Encodable<Asn1Sequence>, Identifiable {
return EC.fromUncompressed(curve, x, y)
}

Rsa.oid -> {
RSA.oid -> {
(keyInfo.nextChild() as Asn1Primitive).readNull()
val bitString = (src.nextChild() as Asn1Primitive).asAsn1BitString()
val rsaSequence = Asn1Element.parse(bitString.rawBytes) as Asn1Sequence
val n = (rsaSequence.nextChild() as Asn1Primitive).decode(Asn1Element.Tag.INT) { it }
val e = (rsaSequence.nextChild() as Asn1Primitive).decodeToInt()
if (rsaSequence.hasMoreChildren()) throw Asn1StructuralException("Superfluous data in SPKI!")
return Rsa(n, e)
return RSA(n, e)
}

else -> throw Asn1Exception("Unsupported Key Type: $oid")
Expand All @@ -159,7 +159,7 @@ sealed class CryptoPublicKey : Asn1Encodable<Asn1Sequence>, Identifiable {
}

//TODO: this could be nicer, maybe?
(BERTags.SEQUENCE or BERTags.CONSTRUCTED) -> Rsa.fromPKCS1encoded(it)
(BERTags.SEQUENCE or BERTags.CONSTRUCTED) -> RSA.fromPKCS1encoded(it)
else -> throw IllegalArgumentException("Unsupported Key type")
}

Expand All @@ -170,7 +170,7 @@ sealed class CryptoPublicKey : Asn1Encodable<Asn1Sequence>, Identifiable {
*/
@Serializable
@ConsistentCopyVisibility
data class Rsa
data class RSA
@Throws(IllegalArgumentException::class)
private constructor(
/**
Expand Down Expand Up @@ -207,7 +207,7 @@ sealed class CryptoPublicKey : Asn1Encodable<Asn1Sequence>, Identifiable {
@Throws(IllegalArgumentException::class)
constructor(n: ByteArray, e: Int) : this(sanitizeRsaInputs(n, e))

override val oid = Rsa.oid
override val oid = RSA.oid

/**
* enum of supported RSA key sized. For sanity checks!
Expand Down Expand Up @@ -263,7 +263,7 @@ sealed class CryptoPublicKey : Asn1Encodable<Asn1Sequence>, Identifiable {
if (other == null) return false
if (this::class != other::class) return false

other as Rsa
other as RSA

return pkcsEncoded.contentEquals(other.pkcsEncoded)
}
Expand All @@ -282,12 +282,12 @@ sealed class CryptoPublicKey : Asn1Encodable<Asn1Sequence>, Identifiable {
* @throws Asn1Exception all sorts of exceptions on invalid input
*/
@Throws(Asn1Exception::class)
fun fromPKCS1encoded(input: ByteArray): Rsa = runRethrowing {
fun fromPKCS1encoded(input: ByteArray): RSA = runRethrowing {
val conv = Asn1Element.parse(input) as Asn1Sequence
val n = (conv.nextChild() as Asn1Primitive).decode(Asn1Element.Tag.INT) { it }
val e = (conv.nextChild() as Asn1Primitive).decodeToInt()
if (conv.hasMoreChildren()) throw Asn1StructuralException("Superfluous bytes")
return Rsa(Size.of(n), n, e)
return RSA(Size.of(n), n, e)
}

override val oid = KnownOIDs.rsaEncryption
Expand Down Expand Up @@ -442,20 +442,20 @@ fun CryptoPublicKey.equalsCryptographically(other: SpecializedCryptoPublicKey) =


//Helper typealias, for helper sanitization function. Enables passing all params along constructors for constructor chaining
private typealias RsaParams = Triple<ByteArray, Int, CryptoPublicKey.Rsa.Size>
private typealias RsaParams = Triple<ByteArray, Int, CryptoPublicKey.RSA.Size>

private val RsaParams.n get() = first
private val RsaParams.e get() = second
private val RsaParams.size get() = third

/**
* Sanitizes RSA parameters and maps it to the correct [CryptoPublicKey.Rsa.Size] enum
* Sanitizes RSA parameters and maps it to the correct [CryptoPublicKey.RSA.Size] enum
* This function lives here and returns a typealiased Triple to allow for constructor chaining.
* If we were to change the primary constructor, we'd need to write a custom serializer
*/
@Throws(IllegalArgumentException::class)
private fun sanitizeRsaInputs(n: ByteArray, e: Int): RsaParams = n.dropWhile { it == 0.toByte() }.toByteArray()
.let { Triple(byteArrayOf(0, *it), e, CryptoPublicKey.Rsa.Size.of(it)) }
.let { Triple(byteArrayOf(0, *it), e, CryptoPublicKey.RSA.Size.of(it)) }


private val PREFIX_DID_KEY = "did:key"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ fun ECCurve.Companion.byJcaName(name: String): ECCurve? = ECCurve.entries.find {

fun CryptoPublicKey.getJcaPublicKey() = when (this) {
is CryptoPublicKey.EC -> getJcaPublicKey()
is CryptoPublicKey.Rsa -> getJcaPublicKey()
is CryptoPublicKey.RSA -> getJcaPublicKey()
}

fun CryptoPublicKey.EC.getJcaPublicKey(): KmmResult<ECPublicKey> = catching {
Expand All @@ -137,7 +137,7 @@ fun CryptoPublicKey.EC.getJcaPublicKey(): KmmResult<ECPublicKey> = catching {

private val rsaFactory = KeyFactory.getInstance("RSA")

fun CryptoPublicKey.Rsa.getJcaPublicKey(): KmmResult<RSAPublicKey> = catching {
fun CryptoPublicKey.RSA.getJcaPublicKey(): KmmResult<RSAPublicKey> = catching {
rsaFactory.generatePublic(
RSAPublicKeySpec(BigInteger(1, n), BigInteger.valueOf(e.toLong()))
) as RSAPublicKey
Expand All @@ -158,12 +158,12 @@ fun CryptoPublicKey.EC.Companion.fromJcaPublicKey(publicKey: ECPublicKey): KmmRe
)
}

fun CryptoPublicKey.Rsa.Companion.fromJcaPublicKey(publicKey: RSAPublicKey): KmmResult<CryptoPublicKey> =
catching { CryptoPublicKey.Rsa(publicKey.modulus.toByteArray(), publicKey.publicExponent.toInt()) }
fun CryptoPublicKey.RSA.Companion.fromJcaPublicKey(publicKey: RSAPublicKey): KmmResult<CryptoPublicKey> =
catching { CryptoPublicKey.RSA(publicKey.modulus.toByteArray(), publicKey.publicExponent.toInt()) }

fun CryptoPublicKey.Companion.fromJcaPublicKey(publicKey: PublicKey): KmmResult<CryptoPublicKey> =
when (publicKey) {
is RSAPublicKey -> CryptoPublicKey.Rsa.fromJcaPublicKey(publicKey)
is RSAPublicKey -> CryptoPublicKey.RSA.fromJcaPublicKey(publicKey)
is ECPublicKey -> CryptoPublicKey.EC.fromJcaPublicKey(publicKey)
else -> KmmResult.failure(IllegalArgumentException("Unsupported Key Type"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ class PublicKeyTest : FreeSpec({
keys
) { pubKey ->

val own = CryptoPublicKey.Rsa(pubKey.modulus.toByteArray(), pubKey.publicExponent.toInt())
val own1 = CryptoPublicKey.Rsa(
val own = CryptoPublicKey.RSA(pubKey.modulus.toByteArray(), pubKey.publicExponent.toInt())
val own1 = CryptoPublicKey.RSA(
ByteArray((0..10).random()) { 0 } + pubKey.modulus.toByteArray(),
pubKey.publicExponent.toInt()
)
Expand Down
1 change: 0 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ pluginManagement {
google()
mavenLocal()
mavenCentral()
maven("https://s01.oss.sonatype.org/content/repositories/snapshots") //KOTEST snapshot
gradlePluginPortal()
maven {
url = uri("https://raw.githubusercontent.com/a-sit-plus/gradle-conventions-plugin/mvn/repo")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ object AndroidKeyStoreProvider:
val digest = resolveOption("digest", keyInfo.digests, Digest.entries.asSequence() + sequenceOf<Digest?>(null), ecConfig.digestSpecified, { ecConfig.digest }) { it?.jcaName ?: KeyProperties.DIGEST_NONE }
SignatureAlgorithm.ECDSA(digest, publicKey.curve)
}
is CryptoPublicKey.Rsa -> {
is CryptoPublicKey.RSA -> {
val rsaConfig = config.rsa.v
val digest = resolveOption<Digest>("digest", keyInfo.digests, Digest.entries.asSequence(), rsaConfig.digestSpecified, { rsaConfig.digest }, Digest::jcaName)
val padding = resolveOption<RSAPadding>("padding", keyInfo.signaturePaddings, RSAPadding.entries.asSequence(), rsaConfig.paddingSpecified, { rsaConfig.padding }) {
Expand All @@ -273,7 +273,7 @@ object AndroidKeyStoreProvider:
AndroidKeystoreSigner.ECDSA(
jcaPrivateKey, alias, keyInfo, config, publicKey,
attestation, algorithm as SignatureAlgorithm.ECDSA)
is CryptoPublicKey.Rsa ->
is CryptoPublicKey.RSA ->
AndroidKeystoreSigner.RSA(
jcaPrivateKey, alias, keyInfo, config, publicKey,
attestation, algorithm as SignatureAlgorithm.RSA)
Expand Down Expand Up @@ -400,7 +400,7 @@ sealed class AndroidKeystoreSigner private constructor(
alias: String,
keyInfo: KeyInfo,
config: AndroidSignerConfiguration,
override val publicKey: CryptoPublicKey.Rsa,
override val publicKey: CryptoPublicKey.RSA,
attestation: AndroidKeystoreAttestation?,
override val signatureAlgorithm: SignatureAlgorithm.RSA)
: AndroidKeystoreSigner(jcaPrivateKey, alias, keyInfo, config, attestation), SignerI.RSA
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ sealed class AndroidEphemeralSigner (internal val privateKey: PrivateKey) : Sign
}

class RSA (config: EphemeralSignerConfiguration, privateKey: PrivateKey,
override val publicKey: CryptoPublicKey.Rsa, override val signatureAlgorithm: SignatureAlgorithm.RSA)
override val publicKey: CryptoPublicKey.RSA, override val signatureAlgorithm: SignatureAlgorithm.RSA)
: AndroidEphemeralSigner(privateKey), Signer.RSA {

override fun parseFromJca(bytes: ByteArray) = CryptoSignature.RSAorHMAC.parseFromJca(bytes)
Expand All @@ -64,7 +64,7 @@ internal actual fun makeEphemeralKey(configuration: EphemeralSigningKeyConfigura
generateKeyPair()
}.let { pair ->
EphemeralKeyBase.RSA(AndroidEphemeralSigner::RSA,
pair.private, CryptoPublicKey.fromJcaPublicKey(pair.public).getOrThrow() as CryptoPublicKey.Rsa,
pair.private, CryptoPublicKey.fromJcaPublicKey(pair.public).getOrThrow() as CryptoPublicKey.RSA,
digests = alg.digests, paddings = alg.paddings)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import at.asitplus.signum.indispensable.jcaAlgorithmComponent
import at.asitplus.signum.indispensable.jcaSignatureBytes
import at.asitplus.signum.supreme.dsl.DSL
import at.asitplus.signum.supreme.UnsupportedCryptoException
import at.asitplus.signum.supreme.sign.InvalidSignature
import at.asitplus.signum.supreme.sign.PlatformVerifierConfiguration
import at.asitplus.signum.supreme.sign.SignatureInput
import at.asitplus.wrapping
import java.security.Signature

Expand Down Expand Up @@ -70,7 +67,7 @@ private fun getRSAInstance(alg: SignatureAlgorithm.RSA, config: PlatformVerifier

@Throws(UnsupportedCryptoException::class)
internal actual fun checkAlgorithmKeyCombinationSupportedByRSAPlatformVerifier
(signatureAlgorithm: SignatureAlgorithm.RSA, publicKey: CryptoPublicKey.Rsa,
(signatureAlgorithm: SignatureAlgorithm.RSA, publicKey: CryptoPublicKey.RSA,
config: PlatformVerifierConfiguration)
{
wrapping(asA=::UnsupportedCryptoException) {
Expand All @@ -81,7 +78,7 @@ internal actual fun checkAlgorithmKeyCombinationSupportedByRSAPlatformVerifier

@JvmSynthetic
internal actual fun verifyRSAImpl
(signatureAlgorithm: SignatureAlgorithm.RSA, publicKey: CryptoPublicKey.Rsa,
(signatureAlgorithm: SignatureAlgorithm.RSA, publicKey: CryptoPublicKey.RSA,
data: SignatureInput, signature: CryptoSignature.RSAorHMAC,
config: PlatformVerifierConfiguration)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import at.asitplus.signum.indispensable.Digest
import at.asitplus.signum.indispensable.RSAPadding
import at.asitplus.signum.indispensable.SignatureAlgorithm
import at.asitplus.signum.indispensable.nativeDigest
import at.asitplus.signum.supreme.HazardousMaterials
import at.asitplus.signum.supreme.dsl.DSL
import at.asitplus.signum.supreme.dsl.DSLConfigureFn
import at.asitplus.signum.supreme.os.SignerConfiguration
Expand Down Expand Up @@ -54,7 +53,7 @@ sealed interface EphemeralKey {
}
/** An [EphemeralKey] suitable for RSA operations. */
interface RSA: EphemeralKey {
override val publicKey: CryptoPublicKey.Rsa
override val publicKey: CryptoPublicKey.RSA
override fun signer(configure: DSLConfigureFn<EphemeralSignerConfiguration>): KmmResult<Signer.RSA>
}
companion object {
Expand Down Expand Up @@ -89,8 +88,8 @@ internal sealed class EphemeralKeyBase <PrivateKeyT>
}

class RSA<PrivateKeyT, SignerT: Signer.RSA>(
private val signerFactory: (EphemeralSignerConfiguration, PrivateKeyT, CryptoPublicKey.Rsa, SignatureAlgorithm.RSA)->SignerT,
privateKey: PrivateKeyT, override val publicKey: CryptoPublicKey.Rsa,
private val signerFactory: (EphemeralSignerConfiguration, PrivateKeyT, CryptoPublicKey.RSA, SignatureAlgorithm.RSA)->SignerT,
privateKey: PrivateKeyT, override val publicKey: CryptoPublicKey.RSA,
val digests: Set<Digest>, val paddings: Set<RSAPadding>) : EphemeralKeyBase<PrivateKeyT>(privateKey), EphemeralKey.RSA {

override fun signer(configure: DSLConfigureFn<EphemeralSignerConfiguration>): KmmResult<SignerT> = catching {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ interface Signer {
/** A [Signer] that signs using RSA. */
interface RSA: AlgTrait {
override val signatureAlgorithm: SignatureAlgorithm.RSA
override val publicKey: CryptoPublicKey.Rsa
override val publicKey: CryptoPublicKey.RSA
}

/** Some [Signer]s are retrieved from a signing provider, such as a key store, and have a string [alias]. */
Expand Down
Loading

0 comments on commit 8d66a7e

Please sign in to comment.