libp2p / libp2p/jvm-libp2p

jvm-ibp2p vulnerable to attack using large RSA keys

Open
#405 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Kotlin
Stars
366
Forks
85
Avg merge
2d 39m
Merged PRs (30d)
6

Description

Summary

There is no length limit for RSA keys, and a malicious node can exploit large RSA keys to launch a resource exhaustion attack.
there is a similar problem
The relevant code is in this file.

`

@JvmOverloads
fun generateRsaKeyPair(bits: Int, random: SecureRandom = SecureRandom()): Pair<PrivKey, PubKey> {
if (bits < 2048) {
throw Libp2pException(ERR_RSA_KEY_TOO_SMALL)
}

val kp: KeyPair = with(
    KeyPairGenerator.getInstance(
        RSA_ALGORITHM,
        Libp2pCrypto.provider
    )
) {
    initialize(bits, random)
    genKeyPair()
}

return Pair(
    RsaPrivateKey(kp.private, kp.public),
    RsaPublicKey(kp.public)
)

}

/**

  • Unmarshals the given key bytes into an RSA public key instance.
  • @param keyBytes the key bytes.
  • @return a private key.
    */
    fun unmarshalRsaPublicKey(keyBytes: ByteArray): PubKey =
    RsaPublicKey(
    KeyFactory.getInstance(
    RSA_ALGORITHM,
    Libp2pCrypto.provider
    ).generatePublic(X509EncodedKeySpec(keyBytes))
    )

/**

  • Unmarshals the given key bytes (in PKCS1 format) into an RSA PKCS8 private key instance.

  • @param keyBytes the key bytes.

  • @return a private key instance.
    */
    fun unmarshalRsaPrivateKey(keyBytes: ByteArray): PrivKey {
    // Input is ASN1 DER encoded PKCS1 private key bytes.
    val rsaPrivateKey = RSAPrivateKey.getInstance(ASN1Primitive.fromByteArray(keyBytes))
    val privateKeyParameters = RSAPrivateCrtKeyParameters(
    rsaPrivateKey.modulus,
    rsaPrivateKey.publicExponent,
    rsaPrivateKey.privateExponent,
    rsaPrivateKey.prime1,
    rsaPrivateKey.prime2,
    rsaPrivateKey.exponent1,
    rsaPrivateKey.exponent2,
    rsaPrivateKey.coefficient
    )

    // Now convert to a PKSC#8 key.
    val privateKeyInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(privateKeyParameters)
    val algorithmId = privateKeyInfo.privateKeyAlgorithm.algorithm.id
    val spec = PKCS8EncodedKeySpec(privateKeyInfo.encoded)
    val sk = KeyFactory.getInstance(algorithmId, Libp2pCrypto.provider).generatePrivate(spec)

    // We can extract the public key from the modulus and exponent of the private key. Woot!
    val publicKeySpec = RSAPublicKeySpec(privateKeyParameters.modulus, privateKeyParameters.publicExponent)
    val keyFactory = KeyFactory.getInstance(RSA_ALGORITHM)
    val pk = keyFactory.generatePublic(publicKeySpec)

    return RsaPrivateKey(sk, pk)
    }

`

Expected behavior

Limit the RSA key length.

Actual behavior

When a large number of long RSA keys are maliciously generated and parsed, it can consume a significant amount of resources.

Relevant log output

Possible Solution

The vulnerability can be fixed by restricting the length of RSA keys. it is similar to this.
the problem may be in this file.

Version

before the latest version

Would you like to work on fixing this bug ?

Yes

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked libp2p/src/main/kotlin/io/libp2p/crypto/keys/Rsa.kt, especially generateRsaKeyPair and the public and private key unmarshalling entry points. Trace how RSA key sizes are parsed and identify the existing crypto tests, if any, that cover these paths. Done means oversized RSA keys are rejected before they can cause excessive resource use, with regression coverage for the limit.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin
Domain
cryptography, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.