4

X.509 Certificates in Kotlin

 3 years ago
source link: https://publicobject.com/2020/06/30/a-kotlin-tls-certificate/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

X.509 Certificates in Kotlin

Published on 2020-06-30

I learned most of what I know about TLS certificates through reading APIs, source code, and specs. My instincts from dealing with ASN.1, X.509, and TLS as a user is that it the APIs are complex, and I should stay away️ from the even more complex implementations.

But I’m foolish and I don’t like that okhttp-tls depends on Bouncy Castle to create certificates. “How hard could it be to create a well-formed TLS certificate? It’s just bytes!...”

So I read lots of specs. I found these difficult to learn from because they aren’t self-contained. Each builds upon others and some go back to the days before ASCII! But I did find a couple very helpful guides: this one from Let’s Encrypt and one from RSA written in 1993.

Next I started writing tests and code, building up from small ASN.1 primitives all the way to full nested objects with type hints. Yesterday I reached my goal and changed okhttp-tls to not need Bouncy Castle to create certificates. The code that does it is about 2,000 lines of Kotlin. Hooray!

Now that I have the code I’m shocked at how simple this stuff can be. It takes just six data classes to model a signed certificate:

data class Certificate(
  val tbsCertificate: TbsCertificate,
  val signatureAlgorithm: AlgorithmIdentifier,
  val signatureValue: ByteString
)

data class TbsCertificate(
  val version: Long,
  val serialNumber: BigInteger,
  val signature: AlgorithmIdentifier,
  val issuer: Map<String, Any?>,
  val validity: Validity,
  val subject: Map<String, Any?>,
  val subjectPublicKeyInfo: SubjectPublicKeyInfo,
  val extensions: List<Extension>
)

data class AlgorithmIdentifier(
  val algorithm: String,
  val parameters: Any?
)

data class Validity(
  val notBefore: Instant,
  val notAfter: Instant
)

data class SubjectPublicKeyInfo(
  val algorithm: AlgorithmIdentifier,
  val publicKey: ByteString
)

data class Extension(
  val id: String,
  val critical: Boolean,
  val value: Any?
)
12345678910111213141516171819202122232425262728293031323334353637

The above code is simplified from certificates.kt in OkHttp, but not by much. It feels great to learn that certificates aren’t so scary; it was just the specs and APIs that were wrapped around them.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK