Skip to content

Commit

Permalink
fix csr encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
JesusMcCloud committed Oct 8, 2024
1 parent 47cad79 commit b212666
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,18 @@ data class TbsCertificationRequest(
constructor(
subjectName: List<RelativeDistinguishedName>,
publicKey: CryptoPublicKey,
extensions: List<X509CertificateExtension>,
extensions: List<X509CertificateExtension>? = null,
version: Int = 0,
attributes: List<Pkcs10CertificationRequestAttribute>? = null,
) : this(version, subjectName, publicKey, mutableListOf<Pkcs10CertificationRequestAttribute>().also { attrs ->
attributes?.let { attrs.addAll(it) }
attrs.add(Pkcs10CertificationRequestAttribute(KnownOIDs.extensionRequest, Asn1.Sequence {
extensions.forEach { +it }
}))
extensions?.let { extn ->
attrs.add(
Pkcs10CertificationRequestAttribute(
KnownOIDs.extensionRequest,
Asn1.Sequence { extn.forEach { +it } })
)
}
})

override fun encodeToTlv() = Asn1.Sequence {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,50 @@ class Pkcs10CertificationRequestJvmTest : FreeSpec({
parsedFromKotlinCsr.isSignatureValid(JcaContentVerifierProviderBuilder().build(keyPair.public))
}

"CSRs with empty extensions match" {
val ecPublicKey = keyPair.public as ECPublicKey
val cryptoPublicKey = CryptoPublicKey.EC.fromJcaPublicKey(ecPublicKey).getOrThrow()

// create CSR with bouncycastle
val commonName = "localhost"
val signatureAlgorithm = X509SignatureAlgorithm.ES256
val contentSigner: ContentSigner = signatureAlgorithm.getContentSigner(keyPair.private)
val spki = SubjectPublicKeyInfo.getInstance(keyPair.public.encoded)



val bcCsr = PKCS10CertificationRequestBuilder(X500Name("CN=$commonName"), spki)
.addAttribute(ASN1ObjectIdentifier("1.2.1840.13549.1.9.16.1337.26"), ASN1Integer(1337L))
.build(contentSigner)
val tbsCsr = TbsCertificationRequest(
subjectName = listOf(RelativeDistinguishedName(AttributeTypeAndValue.CommonName(Asn1String.UTF8(commonName)))),
publicKey = cryptoPublicKey,
extensions = null,
attributes = listOf(
Pkcs10CertificationRequestAttribute(
ObjectIdentifier("1.2.1840.13549.1.9.16.1337.26"),
1337.encodeToAsn1Primitive()
)
)
)
val signed = signatureAlgorithm.getJCASignatureInstance().getOrThrow().apply {
initSign(keyPair.private)
update(tbsCsr.encodeToTlv().derEncoded)
}.sign()
val csr = Pkcs10CertificationRequest(tbsCsr, signatureAlgorithm, CryptoSignature.parseFromJca(signed,signatureAlgorithm))

val kotlinEncoded = csr.encodeToTlv().derEncoded
val jvmEncoded = bcCsr.encoded
println(jvmEncoded.toHexString(HexFormat.UpperCase))
println(kotlinEncoded.toHexString(HexFormat.UpperCase))
// CSR will never entirely match because of randomness in ECDSA signature
//kotlinEncoded shouldBe jvmEncoded
kotlinEncoded.drop(6).take(152) shouldBe jvmEncoded.drop(6).take(152)

val parsedFromKotlinCsr = PKCS10CertificationRequest(kotlinEncoded)
parsedFromKotlinCsr.isSignatureValid(JcaContentVerifierProviderBuilder().build(keyPair.public))
}

"CSR can be parsed" {
val ecPublicKey = keyPair.public as ECPublicKey
val keyX = ecPublicKey.w.affineX.toByteArray().ensureSize(ecCurve.coordinateLength.bytes)
Expand Down

0 comments on commit b212666

Please sign in to comment.