Skip to content

Commit

Permalink
Conversion of package appverifier > readercertgen to Kotlin (#397)
Browse files Browse the repository at this point in the history
* Conversion of package appverifier > readercertgen to Kotlin

* Changes after feedback from Jovche
  • Loading branch information
keesgeluk authored Oct 30, 2023
1 parent 917feb9 commit aa50f95
Show file tree
Hide file tree
Showing 13 changed files with 244 additions and 329 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.android.mdl.appreader.readercertgen

import org.bouncycastle.asn1.ASN1ObjectIdentifier
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x509.BasicConstraints
import org.bouncycastle.asn1.x509.ExtendedKeyUsage
import org.bouncycastle.asn1.x509.Extension
import org.bouncycastle.asn1.x509.GeneralName
import org.bouncycastle.asn1.x509.GeneralNames
import org.bouncycastle.asn1.x509.KeyPurposeId
import org.bouncycastle.asn1.x509.KeyUsage
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier
import org.bouncycastle.cert.CertIOException
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder
import org.bouncycastle.operator.OperatorCreationException
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder
import java.io.IOException
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.Optional

object CertificateGenerator {
private const val CRITICAL = true
private const val NOT_CRITICAL = false
@JvmStatic
@Throws(CertIOException::class, CertificateException::class, OperatorCreationException::class)
fun generateCertificate(
data: DataMaterial,
certMaterial: CertificateMaterial,
keyMaterial: KeyMaterial
): X509Certificate {
val issuerCert: Optional<X509Certificate> = keyMaterial.issuerCertificate
val subjectDN = X500Name(data.subjectDN)
// doesn't work, get's reordered
// issuerCert.isPresent() ? new X500Name(issuerCert.get().getSubjectX500Principal().getName()) : subjectDN;
val issuerDN = X500Name(data.issuerDN)
val contentSigner =
JcaContentSignerBuilder(keyMaterial.signingAlgorithm).build(keyMaterial.signingKey)
val certBuilder = JcaX509v3CertificateBuilder(
issuerDN,
certMaterial.serialNumber,
certMaterial.startDate, certMaterial.endDate,
subjectDN,
keyMaterial.publicKey
)


// Extensions --------------------------
val jcaX509ExtensionUtils = JcaX509ExtensionUtils()
if (issuerCert.isPresent) {
try {
// adds 3 more fields, not present in other cert
// AuthorityKeyIdentifier authorityKeyIdentifier = jcaX509ExtensionUtils.createAuthorityKeyIdentifier(issuerCert.get());
val authorityKeyIdentifier =
jcaX509ExtensionUtils.createAuthorityKeyIdentifier(issuerCert.get().publicKey)
certBuilder.addExtension(
Extension.authorityKeyIdentifier,
NOT_CRITICAL,
authorityKeyIdentifier
)
} catch (e: IOException) { // CertificateEncodingException |
throw RuntimeException(e)
}
}
val subjectKeyIdentifier: SubjectKeyIdentifier =
jcaX509ExtensionUtils.createSubjectKeyIdentifier(keyMaterial.publicKey)
certBuilder.addExtension(Extension.subjectKeyIdentifier, NOT_CRITICAL, subjectKeyIdentifier)
val keyUsage = KeyUsage(certMaterial.keyUsage)
certBuilder.addExtension(Extension.keyUsage, CRITICAL, keyUsage)

// IssuerAlternativeName
val issuerAlternativeName: Optional<String> = data.issuerAlternativeName
if (issuerAlternativeName.isPresent) {
val issuerAltName = GeneralNames(
GeneralName(
GeneralName.uniformResourceIdentifier,
issuerAlternativeName.get()
)
)
certBuilder.addExtension(Extension.issuerAlternativeName, NOT_CRITICAL, issuerAltName)
}

// Basic Constraints
val pathLengthConstraint: Int = certMaterial.pathLengthConstraint
if (pathLengthConstraint != CertificateMaterial.PATHLENGTH_NOT_A_CA) {
// TODO doesn't work for certificate chains != 2 in size
val basicConstraints = BasicConstraints(pathLengthConstraint)
certBuilder.addExtension(Extension.basicConstraints, CRITICAL, basicConstraints)
}
val extendedKeyUsage: Optional<String> = certMaterial.extendedKeyUsage
if (extendedKeyUsage.isPresent) {
val keyPurpose = KeyPurposeId.getInstance(ASN1ObjectIdentifier(extendedKeyUsage.get()))
val extKeyUsage = ExtendedKeyUsage(arrayOf(keyPurpose))
certBuilder.addExtension(Extension.extendedKeyUsage, CRITICAL, extKeyUsage)
}

// DEBUG setProvider(bcProvider) removed before getCertificate
return JcaX509CertificateConverter().getCertificate(certBuilder.build(contentSigner))
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.android.mdl.appreader.readercertgen

import java.math.BigInteger
import java.util.Date
import java.util.Optional

data class CertificateMaterial(
val serialNumber: BigInteger,
val startDate: Date,
val endDate: Date,
val keyUsage: Int,
val extendedKeyUsage: Optional<String>,
val pathLengthConstraint: Int
) {
companion object {
const val PATHLENGTH_NOT_A_CA = -1
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.android.mdl.appreader.readercertgen

import java.util.Optional

data class DataMaterial(
val subjectDN: String,
val issuerDN: String,
val issuerAlternativeName: Optional<String>
)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.android.mdl.appreader.readercertgen

import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

object EncodingUtil {
private val SHORT_ISO_DATEFORMAT = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
fun parseShortISODate(date: String): Date {
return try {
SHORT_ISO_DATEFORMAT.parse(date)!!
} catch (e: ParseException) {
throw RuntimeException(e)
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.android.mdl.appreader.readercertgen

import java.security.PrivateKey
import java.security.PublicKey
import java.security.cert.X509Certificate
import java.util.Optional

data class KeyMaterial(
val publicKey: PublicKey,
val signingAlgorithm: String,
val issuerCertificate: Optional<X509Certificate>,
val signingKey: PrivateKey
)
Loading

0 comments on commit aa50f95

Please sign in to comment.