From 6a339021221346577e2180110824b49c023e3692 Mon Sep 17 00:00:00 2001 From: Jonathan Lennox Date: Fri, 6 Dec 2024 11:59:26 -0500 Subject: [PATCH 1/2] Support "no signature" signers on local X.509 certificates. As defined in draft-davidben-x509-alg-none. --- .../kotlin/org/jitsi/nlj/dtls/DtlsConfig.kt | 4 +++ .../kotlin/org/jitsi/nlj/dtls/DtlsUtils.kt | 6 +++- .../org/jitsi/nlj/dtls/NoSignatureSigner.kt | 33 +++++++++++++++++++ .../src/main/resources/reference.conf | 3 +- 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/NoSignatureSigner.kt diff --git a/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/DtlsConfig.kt b/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/DtlsConfig.kt index 40f689da7e..13fe5bdec9 100644 --- a/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/DtlsConfig.kt +++ b/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/DtlsConfig.kt @@ -54,6 +54,10 @@ class DtlsConfig { } } + val useNoSignatureSigner: Boolean by config { + "jmt.dtls.use-no-signature-signer".from(JitsiConfig.newConfig) + } + companion object { val config = DtlsConfig() } diff --git a/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/DtlsUtils.kt b/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/DtlsUtils.kt index 6915fa3d04..478d832dc6 100644 --- a/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/DtlsUtils.kt +++ b/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/DtlsUtils.kt @@ -114,7 +114,11 @@ class DtlsUtils { subject, keyPair.public ) - val signer = JcaContentSignerBuilder("SHA256withECDSA").build(keyPair.private) + val signer = if (config.useNoSignatureSigner) { + NoSignatureSigner() + } else { + JcaContentSignerBuilder("SHA256withECDSA").build(keyPair.private) + } return certBuilder.build(signer).toASN1Structure() } diff --git a/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/NoSignatureSigner.kt b/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/NoSignatureSigner.kt new file mode 100644 index 0000000000..72f35001cc --- /dev/null +++ b/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/NoSignatureSigner.kt @@ -0,0 +1,33 @@ +package org.jitsi.nlj.dtls + +import org.bouncycastle.asn1.ASN1ObjectIdentifier +import org.bouncycastle.asn1.x509.AlgorithmIdentifier +import org.bouncycastle.operator.ContentSigner +import java.io.OutputStream + +/** + * A "signing" algorithm which produces an empty signature. Based on + * draft-davidben-x509-alg-none. + * Should be treated as an unknown algorithm by all recipients, so any attempt to + * validate it will return false. + */ +class NoSignatureSigner : ContentSigner { + override fun getAlgorithmIdentifier(): AlgorithmIdentifier { + return identifier + } + + override fun getOutputStream(): OutputStream { + return OutputStream.nullOutputStream() + } + + override fun getSignature(): ByteArray { + return ByteArray(0) + } + + companion object { + // A random OID we're squatting on, in the Columbia University number space. + // (Registered in 1997, apparently unused since then.) + // To be replaced with an IETF-assigned one if and when one is assigned. + private val identifier = AlgorithmIdentifier(ASN1ObjectIdentifier("1.2.840.113560.420.69")) + } +} diff --git a/jitsi-media-transform/src/main/resources/reference.conf b/jitsi-media-transform/src/main/resources/reference.conf index 9fc672b7a0..d84e58da0a 100644 --- a/jitsi-media-transform/src/main/resources/reference.conf +++ b/jitsi-media-transform/src/main/resources/reference.conf @@ -47,7 +47,8 @@ jmt { local-fingerprint-hash-function = sha-256 // The hash functions that are accepted for remote certificate fingerprints, in decreasing strength order accepted-fingerprint-hash-functions = [ sha-512, sha-384, sha-256, sha-1 ] - + // Whether to use the "no-signature" signer rather than self-signing the local certificate + use-no-signature-signer = true } srtp { // The maximum number of packets that can be discarded early (without going through the SRTP stack for From dd69880a9aae135ceb78777f87bc47061fb1a24f Mon Sep 17 00:00:00 2001 From: Jonathan Lennox Date: Wed, 18 Dec 2024 13:06:10 -0500 Subject: [PATCH 2/2] Update to assigned OID, following draft-davidben-x509-alg-none-01. --- .../org/jitsi/nlj/dtls/NoSignatureSigner.kt | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/NoSignatureSigner.kt b/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/NoSignatureSigner.kt index 72f35001cc..ec9a32fa8a 100644 --- a/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/NoSignatureSigner.kt +++ b/jitsi-media-transform/src/main/kotlin/org/jitsi/nlj/dtls/NoSignatureSigner.kt @@ -1,6 +1,7 @@ package org.jitsi.nlj.dtls import org.bouncycastle.asn1.ASN1ObjectIdentifier +import org.bouncycastle.asn1.DERNull import org.bouncycastle.asn1.x509.AlgorithmIdentifier import org.bouncycastle.operator.ContentSigner import java.io.OutputStream @@ -21,13 +22,26 @@ class NoSignatureSigner : ContentSigner { } override fun getSignature(): ByteArray { + /* + The Certificate's signatureValue field MUST be a BIT STRING of length zero. + */ return ByteArray(0) } companion object { - // A random OID we're squatting on, in the Columbia University number space. - // (Registered in 1997, apparently unused since then.) - // To be replaced with an IETF-assigned one if and when one is assigned. - private val identifier = AlgorithmIdentifier(ASN1ObjectIdentifier("1.2.840.113560.420.69")) + private val identifier = AlgorithmIdentifier( + /* + id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) + dod(6) internet(1) security(5) mechanisms(5) pkix(7) } + + id-alg-noSignature OBJECT IDENTIFIER ::= {id-pkix id-alg(6) 2} + */ + ASN1ObjectIdentifier("1.3.6.1.5.5.7.6.2"), + /* + The parameters for id-alg-noSignature MUST be present + and MUST be encoded as NULL. + */ + DERNull.INSTANCE + ) } }