@@ -23,8 +23,6 @@ package ee.ria.DigiDoc.configuration.utils
2323
2424import ee.ria.DigiDoc.utilsLib.logging.LoggingUtil.Companion.errorLog
2525import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
26- import org.bouncycastle.crypto.params.RSAKeyParameters
27- import org.bouncycastle.crypto.util.PublicKeyFactory
2826import org.bouncycastle.openssl.PEMParser
2927import java.io.IOException
3028import java.io.StringReader
@@ -35,8 +33,9 @@ import java.security.NoSuchAlgorithmException
3533import java.security.PublicKey
3634import java.security.Signature
3735import java.security.SignatureException
36+ import java.security.interfaces.ECPublicKey
3837import java.security.spec.InvalidKeySpecException
39- import java.security.spec.RSAPublicKeySpec
38+ import java.security.spec.X509EncodedKeySpec
4039
4140object SignatureVerifier {
4241 private val LOG_TAG = javaClass.simpleName
@@ -46,45 +45,48 @@ object SignatureVerifier {
4645 publicKeyPEM : String ,
4746 signedContent : String ,
4847 ): Boolean {
49- val publicKeyInfo: SubjectPublicKeyInfo =
50- parsePublicKeyInfo(publicKeyPEM)
48+ val publicKeyInfo = parsePublicKeyInfo(publicKeyPEM)
5149 val publicKey = convertPublicKeyInfoToPublicKey(publicKeyInfo)
5250 return verifySignature(signature, publicKey, signedContent)
5351 }
5452
5553 private fun convertPublicKeyInfoToPublicKey (publicKeyInfo : SubjectPublicKeyInfo ): PublicKey =
5654 try {
57- val keyParams: RSAKeyParameters =
58- PublicKeyFactory .createKey(publicKeyInfo) as RSAKeyParameters
59- val publicKeySpec = RSAPublicKeySpec (keyParams.modulus, keyParams.exponent)
60- val keyFactory = KeyFactory .getInstance(" RSA" )
61- keyFactory.generatePublic(publicKeySpec)
55+ val keySpec = X509EncodedKeySpec (publicKeyInfo.encoded)
56+ val keyFactory = KeyFactory .getInstance(" EC" )
57+ keyFactory.generatePublic(keySpec)
6258 } catch (e: InvalidKeySpecException ) {
6359 errorLog(LOG_TAG , " PublicKey conversion failed" , e)
6460 throw IllegalStateException (
65- " Failed to convert org.bouncycastle.asn1.x509. SubjectPublicKeyInfo to kotlin .security.PublicKey" ,
61+ " Failed to convert SubjectPublicKeyInfo to EC java .security.PublicKey" ,
6662 e,
6763 )
6864 } catch (e: NoSuchAlgorithmException ) {
6965 errorLog(LOG_TAG , " PublicKey conversion failed" , e)
7066 throw IllegalStateException (
71- " Failed to convert org.bouncycastle.asn1.x509. SubjectPublicKeyInfo to kotlin .security.PublicKey" ,
67+ " Failed to convert SubjectPublicKeyInfo to EC java .security.PublicKey" ,
7268 e,
7369 )
7470 } catch (e: IOException ) {
7571 errorLog(LOG_TAG , " PublicKey conversion failed" , e)
7672 throw IllegalStateException (
77- " Failed to convert org.bouncycastle.asn1.x509. SubjectPublicKeyInfo to kotlin .security.PublicKey" ,
73+ " Failed to convert SubjectPublicKeyInfo to EC java .security.PublicKey" ,
7874 e,
7975 )
8076 }
8177
82- private fun parsePublicKeyInfo (PKCS1PublicKeyPEM : String ): SubjectPublicKeyInfo {
78+ private fun parsePublicKeyInfo (publicKeyPem : String ): SubjectPublicKeyInfo {
8379 try {
84- PEMParser (StringReader (PKCS1PublicKeyPEM ))
85- .use { pemParser -> return pemParser.readObject() as SubjectPublicKeyInfo }
80+ PEMParser (StringReader (publicKeyPem)).use { pemParser ->
81+ return pemParser.readObject() as SubjectPublicKeyInfo
82+ }
8683 } catch (e: IOException ) {
87- throw IllegalStateException (" Failed to parse PEM encoded PKCS#1 public key" , e)
84+ throw IllegalStateException (" Failed to parse PEM encoded public key" , e)
85+ } catch (e: ClassCastException ) {
86+ throw IllegalStateException (
87+ " PEM did not contain SubjectPublicKeyInfo. Make sure it's 'BEGIN PUBLIC KEY' (SPKI)." ,
88+ e,
89+ )
8890 }
8991 }
9092
@@ -94,10 +96,13 @@ object SignatureVerifier {
9496 signedContent : String ,
9597 ): Boolean =
9698 try {
97- val signature = Signature .getInstance(" SHA512withRSA" )
99+ val jcaAlg = pickEcdsaAlgorithm(publicKey)
100+ val signature = Signature .getInstance(jcaAlg)
98101 signature.initVerify(publicKey)
99102 signature.update(signedContent.toByteArray(StandardCharsets .UTF_8 ))
100- signature.verify(signatureBytes)
103+ val result = signature.verify(signatureBytes)
104+
105+ result
101106 } catch (e: NoSuchAlgorithmException ) {
102107 errorLog(LOG_TAG , " Signature verification failed" , e)
103108 throw IllegalStateException (" Failed to verify signature" , e)
@@ -107,5 +112,22 @@ object SignatureVerifier {
107112 } catch (e: InvalidKeyException ) {
108113 errorLog(LOG_TAG , " Signature verification failed" , e)
109114 throw IllegalStateException (" Failed to verify signature" , e)
115+ } catch (e: java.lang.Exception ) {
116+ errorLog(LOG_TAG , " Signature verification failed" , e)
117+ throw IllegalStateException (" Failed to verify signature" , e)
110118 }
119+
120+ private fun pickEcdsaAlgorithm (publicKey : PublicKey ): String {
121+ val ecKey =
122+ publicKey as ? ECPublicKey
123+ ? : throw IllegalStateException (" Public key is not EC (ECDSA). Got: ${publicKey.algorithm} " )
124+
125+ val fieldSizeBits = ecKey.params.curve.field.fieldSize
126+
127+ return when {
128+ fieldSizeBits <= 256 -> " SHA256withECDSA"
129+ fieldSizeBits <= 384 -> " SHA384withECDSA"
130+ else -> " SHA512withECDSA"
131+ }
132+ }
111133}
0 commit comments