|  | 
|  | 1 | +/* | 
|  | 2 | + * Copyright (c) 2025 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license. | 
|  | 3 | + */ | 
|  | 4 | + | 
|  | 5 | +package dev.whyoleg.cryptography.providers.openssl3.algorithms | 
|  | 6 | + | 
|  | 7 | +import dev.whyoleg.cryptography.algorithms.* | 
|  | 8 | +import dev.whyoleg.cryptography.materials.key.* | 
|  | 9 | +import dev.whyoleg.cryptography.operations.* | 
|  | 10 | +import dev.whyoleg.cryptography.providers.base.* | 
|  | 11 | +import dev.whyoleg.cryptography.providers.openssl3.internal.* | 
|  | 12 | +import dev.whyoleg.cryptography.providers.openssl3.internal.cinterop.* | 
|  | 13 | +import dev.whyoleg.cryptography.providers.openssl3.materials.* | 
|  | 14 | +import kotlinx.cinterop.* | 
|  | 15 | +import platform.posix.* | 
|  | 16 | +import kotlin.experimental.* | 
|  | 17 | +import dev.whyoleg.cryptography.serialization.asn1.modules.* | 
|  | 18 | +import dev.whyoleg.cryptography.serialization.asn1.ObjectIdentifier | 
|  | 19 | +import dev.whyoleg.cryptography.providers.base.materials.* | 
|  | 20 | +import dev.whyoleg.cryptography.providers.openssl3.operations.Openssl3DigestSignatureGenerator | 
|  | 21 | +import dev.whyoleg.cryptography.providers.openssl3.operations.Openssl3DigestSignatureVerifier | 
|  | 22 | + | 
|  | 23 | +internal object Openssl3EdDSA : EdDSA { | 
|  | 24 | +    private fun algorithmName(curve: EdDSA.Curve): String = when (curve) { | 
|  | 25 | +        EdDSA.Curve.Ed25519 -> "ED25519" | 
|  | 26 | +        EdDSA.Curve.Ed448   -> "ED448" | 
|  | 27 | +    } | 
|  | 28 | +    private fun oid(curve: EdDSA.Curve): ObjectIdentifier = when (curve) { | 
|  | 29 | +        EdDSA.Curve.Ed25519 -> EdwardsOids.Ed25519 | 
|  | 30 | +        EdDSA.Curve.Ed448   -> EdwardsOids.Ed448 | 
|  | 31 | +    } | 
|  | 32 | + | 
|  | 33 | +    override fun publicKeyDecoder(curve: EdDSA.Curve): KeyDecoder<EdDSA.PublicKey.Format, EdDSA.PublicKey> = | 
|  | 34 | +        object : Openssl3PublicKeyDecoder<EdDSA.PublicKey.Format, EdDSA.PublicKey>(algorithmName(curve)) { | 
|  | 35 | +            override fun inputType(format: EdDSA.PublicKey.Format): String = when (format) { | 
|  | 36 | +                EdDSA.PublicKey.Format.DER -> "DER" | 
|  | 37 | +                EdDSA.PublicKey.Format.PEM -> "PEM" | 
|  | 38 | +                EdDSA.PublicKey.Format.JWK, | 
|  | 39 | +                EdDSA.PublicKey.Format.RAW -> error("should not be called: handled explicitly in decodeFromBlocking") | 
|  | 40 | +            } | 
|  | 41 | + | 
|  | 42 | +            override fun decodeFromByteArrayBlocking(format: EdDSA.PublicKey.Format, bytes: ByteArray): EdDSA.PublicKey = when (format) { | 
|  | 43 | +                EdDSA.PublicKey.Format.RAW -> super.decodeFromByteArrayBlocking( | 
|  | 44 | +                    EdDSA.PublicKey.Format.DER, | 
|  | 45 | +                    wrapSubjectPublicKeyInfo(UnknownKeyAlgorithmIdentifier(oid(curve)), bytes) | 
|  | 46 | +                ) | 
|  | 47 | +                else -> super.decodeFromByteArrayBlocking(format, bytes) | 
|  | 48 | +            } | 
|  | 49 | + | 
|  | 50 | +            override fun wrapKey(key: CPointer<EVP_PKEY>): EdDSA.PublicKey = EdDsaPublicKey(key, curve) | 
|  | 51 | +        } | 
|  | 52 | + | 
|  | 53 | +    override fun privateKeyDecoder(curve: EdDSA.Curve): KeyDecoder<EdDSA.PrivateKey.Format, EdDSA.PrivateKey> = | 
|  | 54 | +        object : Openssl3PrivateKeyDecoder<EdDSA.PrivateKey.Format, EdDSA.PrivateKey>(algorithmName(curve)) { | 
|  | 55 | +            override fun inputType(format: EdDSA.PrivateKey.Format): String = when (format) { | 
|  | 56 | +                EdDSA.PrivateKey.Format.DER -> "DER" | 
|  | 57 | +                EdDSA.PrivateKey.Format.PEM -> "PEM" | 
|  | 58 | +                EdDSA.PrivateKey.Format.JWK, | 
|  | 59 | +                EdDSA.PrivateKey.Format.RAW -> error("should not be called: handled explicitly in decodeFromBlocking") | 
|  | 60 | +            } | 
|  | 61 | + | 
|  | 62 | +            override fun decodeFromByteArrayBlocking(format: EdDSA.PrivateKey.Format, bytes: ByteArray): EdDSA.PrivateKey = when (format) { | 
|  | 63 | +                EdDSA.PrivateKey.Format.RAW -> super.decodeFromByteArrayBlocking( | 
|  | 64 | +                    EdDSA.PrivateKey.Format.DER, | 
|  | 65 | +                    wrapPrivateKeyInfo(0, UnknownKeyAlgorithmIdentifier(oid(curve)), bytes) | 
|  | 66 | +                ) | 
|  | 67 | +                else -> super.decodeFromByteArrayBlocking(format, bytes) | 
|  | 68 | +            } | 
|  | 69 | + | 
|  | 70 | +            override fun wrapKey(key: CPointer<EVP_PKEY>): EdDSA.PrivateKey = EdDsaPrivateKey(key, curve) | 
|  | 71 | +        } | 
|  | 72 | + | 
|  | 73 | +    override fun keyPairGenerator(curve: EdDSA.Curve): KeyGenerator<EdDSA.KeyPair> = | 
|  | 74 | +        object : Openssl3KeyPairGenerator<EdDSA.KeyPair>(algorithmName(curve)) { | 
|  | 75 | +            override fun MemScope.createParams(): CValuesRef<OSSL_PARAM>? = null | 
|  | 76 | +            override fun wrapKeyPair(keyPair: CPointer<EVP_PKEY>): EdDSA.KeyPair = EdDsaKeyPair( | 
|  | 77 | +                publicKey = EdDsaPublicKey(keyPair, curve), | 
|  | 78 | +                privateKey = EdDsaPrivateKey(keyPair, curve) | 
|  | 79 | +            ) | 
|  | 80 | +        } | 
|  | 81 | + | 
|  | 82 | +    private class EdDsaKeyPair( | 
|  | 83 | +        override val publicKey: EdDSA.PublicKey, | 
|  | 84 | +        override val privateKey: EdDSA.PrivateKey, | 
|  | 85 | +    ) : EdDSA.KeyPair | 
|  | 86 | + | 
|  | 87 | +    private class EdDsaPublicKey( | 
|  | 88 | +        key: CPointer<EVP_PKEY>, | 
|  | 89 | +        private val curve: EdDSA.Curve, | 
|  | 90 | +    ) : EdDSA.PublicKey, Openssl3PublicKeyEncodable<EdDSA.PublicKey.Format>(key) { | 
|  | 91 | +        override fun outputType(format: EdDSA.PublicKey.Format): String = when (format) { | 
|  | 92 | +            EdDSA.PublicKey.Format.DER -> "DER" | 
|  | 93 | +            EdDSA.PublicKey.Format.PEM -> "PEM" | 
|  | 94 | +            EdDSA.PublicKey.Format.JWK, | 
|  | 95 | +            EdDSA.PublicKey.Format.RAW -> error("should not be called: handled explicitly in encodeToBlocking") | 
|  | 96 | +        } | 
|  | 97 | + | 
|  | 98 | +        override fun encodeToByteArrayBlocking(format: EdDSA.PublicKey.Format): ByteArray = when (format) { | 
|  | 99 | +            EdDSA.PublicKey.Format.RAW -> unwrapSubjectPublicKeyInfo( | 
|  | 100 | +                oid(curve), | 
|  | 101 | +                super.encodeToByteArrayBlocking(EdDSA.PublicKey.Format.DER) | 
|  | 102 | +            ) | 
|  | 103 | +            else -> super.encodeToByteArrayBlocking(format) | 
|  | 104 | +        } | 
|  | 105 | + | 
|  | 106 | +        override fun signatureVerifier(): SignatureVerifier = EdDsaSignatureVerifier(key) | 
|  | 107 | +    } | 
|  | 108 | + | 
|  | 109 | +    private class EdDsaPrivateKey( | 
|  | 110 | +        key: CPointer<EVP_PKEY>, | 
|  | 111 | +        private val curve: EdDSA.Curve, | 
|  | 112 | +    ) : EdDSA.PrivateKey, Openssl3PrivateKeyEncodable<EdDSA.PrivateKey.Format>(key) { | 
|  | 113 | +        override fun outputType(format: EdDSA.PrivateKey.Format): String = when (format) { | 
|  | 114 | +            EdDSA.PrivateKey.Format.DER -> "DER" | 
|  | 115 | +            EdDSA.PrivateKey.Format.PEM -> "PEM" | 
|  | 116 | +            EdDSA.PrivateKey.Format.JWK, | 
|  | 117 | +            EdDSA.PrivateKey.Format.RAW -> error("should not be called: handled explicitly in encodeToBlocking") | 
|  | 118 | +        } | 
|  | 119 | + | 
|  | 120 | +        override fun encodeToByteArrayBlocking(format: EdDSA.PrivateKey.Format): ByteArray = when (format) { | 
|  | 121 | +            EdDSA.PrivateKey.Format.RAW -> unwrapPrivateKeyInfo( | 
|  | 122 | +                oid(curve), | 
|  | 123 | +                super.encodeToByteArrayBlocking(EdDSA.PrivateKey.Format.DER) | 
|  | 124 | +            ) | 
|  | 125 | +            else -> super.encodeToByteArrayBlocking(format) | 
|  | 126 | +        } | 
|  | 127 | + | 
|  | 128 | +        override fun signatureGenerator(): SignatureGenerator = EdDsaSignatureGenerator(key) | 
|  | 129 | +    } | 
|  | 130 | +} | 
|  | 131 | + | 
|  | 132 | + | 
|  | 133 | +private class EdDsaSignatureGenerator( | 
|  | 134 | +    private val privateKey: CPointer<EVP_PKEY>, | 
|  | 135 | +) : Openssl3DigestSignatureGenerator(privateKey, hashAlgorithm = null) { | 
|  | 136 | +    override fun MemScope.createParams(): CValuesRef<OSSL_PARAM>? = null | 
|  | 137 | +} | 
|  | 138 | + | 
|  | 139 | +private class EdDsaSignatureVerifier( | 
|  | 140 | +    private val publicKey: CPointer<EVP_PKEY>, | 
|  | 141 | +) : Openssl3DigestSignatureVerifier(publicKey, hashAlgorithm = null) { | 
|  | 142 | +    override fun MemScope.createParams(): CValuesRef<OSSL_PARAM>? = null | 
|  | 143 | +} | 
0 commit comments