Skip to content

Commit ba484a6

Browse files
committed
chore: Make all public API declarations explicitly public
1 parent 3d4ce7b commit ba484a6

16 files changed

Lines changed: 146 additions & 142 deletions

File tree

module.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ settings:
3232
languageVersion: 2.3
3333
apiVersion: 2.3
3434
progressiveMode: true
35-
allWarningsAsErrors: false
35+
allWarningsAsErrors: true
3636
suppressWarnings: false
3737
powerAssert: enabled
3838
verbose: false
3939
freeCompilerArgs:
40+
- -Xexplicit-api=strict
4041
- -Wextra
4142
- -Xcontext-parameters
4243
- -Xreport-all-warnings
@@ -60,6 +61,8 @@ settings:
6061

6162
test-settings:
6263
kotlin:
64+
freeCompilerArgs:
65+
- -Xexplicit-api=disable
6366
powerAssert:
6467
enabled: true
6568
functions:

src/certkit/cert/Cert.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import kotlinx.datetime.*
3636
* }
3737
* ```
3838
*/
39-
object Cert {
39+
public object Cert {
4040

4141
private val SHA256_ECDSA_OID = Der.oid("1.2.840.10045.4.3.2")
4242
private val SUBJECT_KEY_ID_OID = Der.oid("2.5.29.14")
@@ -53,7 +53,7 @@ object Cert {
5353
* whole-second precision ([RFC 5280 §4.1.2.5.1](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.5.1)).
5454
* Any sub-second component is silently truncated.
5555
*/
56-
fun buildSelfSigned(
56+
public fun buildSelfSigned(
5757
keyPair: KeyPair,
5858
serialNumber: Long = 0,
5959
issuer: X500Principal,
@@ -123,7 +123,7 @@ object Cert {
123123
}
124124

125125
/** Convenience overload that accepts [LocalDate] instead of [Instant]. */
126-
fun buildSelfSigned(
126+
public fun buildSelfSigned(
127127
keyPair: KeyPair,
128128
serialNumber: Long = 0,
129129
issuer: X500Principal,
@@ -143,7 +143,7 @@ object Cert {
143143
sans = sans,
144144
)
145145

146-
fun hashPublicKey(key: ECPublicKey): ByteArray {
146+
public fun hashPublicKey(key: ECPublicKey): ByteArray {
147147
val raw = Der.sequence(Der.integer(key.w.affineX), Der.integer(key.w.affineY))
148148
return MessageDigest.getInstance("SHA-1").digest(raw)
149149
}

src/certkit/cert/Extns.kt

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import javax.naming.ldap.LdapName
55
import kotlin.time.Clock
66
import kotlin.time.Duration
77
import kotlin.time.Instant
8+
import kotlinx.datetime.LocalDateTime
89
import kotlinx.datetime.TimeZone
910
import kotlinx.datetime.toLocalDateTime
1011

1112
/** Returns the subject common name (CN) from the certificate's distinguished name. */
12-
val X509Certificate.commonName: String
13+
public val X509Certificate.commonName: String
1314
get() =
1415
LdapName(subjectX500Principal.name)
1516
.rdns
@@ -22,7 +23,7 @@ val X509Certificate.commonName: String
2223
*
2324
* SAN type OIDs: 1 = RFC822/email, 2 = DNS, 7 = IP address.
2425
*/
25-
val X509Certificate.subjectAltNames: List<String>
26+
public val X509Certificate.subjectAltNames: List<String>
2627
get() =
2728
subjectAlternativeNames
2829
.orEmpty()
@@ -37,11 +38,11 @@ val X509Certificate.subjectAltNames: List<String>
3738
}
3839

3940
/** Returns `true` if this certificate is signed by the given [ca] certificate. */
40-
fun X509Certificate.signedBy(ca: X509Certificate): Boolean =
41+
public fun X509Certificate.signedBy(ca: X509Certificate): Boolean =
4142
issuerX500Principal == ca.subjectX500Principal && runCatching { verify(ca.publicKey) }.isSuccess
4243

4344
/** Returns `true` if this certificate is self-signed. */
44-
val X509Certificate.selfSigned: Boolean
45+
public val X509Certificate.selfSigned: Boolean
4546
get() = signedBy(this)
4647

4748
/**
@@ -54,43 +55,43 @@ val X509Certificate.selfSigned: Boolean
5455
*
5556
* Self-signed certs often include only Basic Constraints without Key Usage.
5657
*/
57-
val X509Certificate.isCA: Boolean
58+
public val X509Certificate.isCA: Boolean
5859
get() = basicConstraints >= 0 || keyUsage?.get(5) == true
5960

6061
/** Returns `true` if this certificate is an intermediate CA (CA but not self-signed). */
61-
val X509Certificate.isIntermediateCA: Boolean
62+
public val X509Certificate.isIntermediateCA: Boolean
6263
get() = isCA && !selfSigned
6364

6465
/** Returns the certificate's start (notBefore) date/time in UTC. */
65-
val X509Certificate.startDateUtc
66+
public val X509Certificate.startDateUtc: LocalDateTime
6667
get() = Instant.fromEpochMilliseconds(notBefore.time).toLocalDateTime(TimeZone.UTC)
6768

6869
/** Returns the certificate's start (notBefore) date/time in the system's local time zone. */
69-
val X509Certificate.startDate
70+
public val X509Certificate.startDate: LocalDateTime
7071
get() =
7172
Instant.fromEpochMilliseconds(notBefore.time).toLocalDateTime(TimeZone.currentSystemDefault())
7273

7374
/** Returns the certificate's expiry (notAfter) date/time in UTC. */
74-
val X509Certificate.expiryDateUtc
75+
public val X509Certificate.expiryDateUtc: LocalDateTime
7576
get() = Instant.fromEpochMilliseconds(notAfter.time).toLocalDateTime(TimeZone.UTC)
7677

7778
/** Returns the certificate's expiry (notAfter) date/time in the system's local time zone. */
78-
val X509Certificate.expiryDate
79+
public val X509Certificate.expiryDate: LocalDateTime
7980
get() =
8081
Instant.fromEpochMilliseconds(notAfter.time).toLocalDateTime(TimeZone.currentSystemDefault())
8182

8283
/** Returns `true` if this certificate has expired. */
83-
val X509Certificate.isExpired: Boolean
84+
public val X509Certificate.isExpired: Boolean
8485
get() = Clock.System.now() > Instant.fromEpochMilliseconds(notAfter.time)
8586

8687
/** Returns the remaining duration until this certificate expires (negative if already expired). */
87-
val X509Certificate.expiresIn: Duration
88+
public val X509Certificate.expiresIn: Duration
8889
get() = Instant.fromEpochMilliseconds(notAfter.time) - Clock.System.now()
8990

9091
/**
9192
* Returns `true` if this certificate chain is signed by one of the given [root] CA certificates.
9293
*/
93-
fun List<X509Certificate>.isSignedByRoot(root: List<X509Certificate>): Boolean {
94+
public fun List<X509Certificate>.isSignedByRoot(root: List<X509Certificate>): Boolean {
9495
check(isNotEmpty()) { "Cert chain is empty" }
9596
val trustAnchors = root.map { TrustAnchor(it, null) }.toSet()
9697
val params = PKIXParameters(trustAnchors).apply { isRevocationEnabled = false }

src/certkit/cert/San.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import certkit.der.Der
44
import java.net.InetAddress
55

66
/** Subject Alternative Name entry for X.509 certificates and CSR extension requests. */
7-
sealed interface San {
8-
data class Dns(val name: String) : San
7+
public sealed interface San {
8+
public data class Dns(val name: String) : San
99

10-
data class Ip(val address: String) : San
10+
public data class Ip(val address: String) : San
1111

12-
data class Email(val address: String) : San
12+
public data class Email(val address: String) : San
1313

1414
/** DER-encodes this SAN as a context-tagged GeneralName (RFC 5280 §4.2.1.6). */
15-
fun toDer(): ByteArray =
15+
public fun toDer(): ByteArray =
1616
when (this) {
1717
is Dns -> Der.implicitTag(2, name.encodeToByteArray())
1818
is Email -> Der.implicitTag(1, address.encodeToByteArray())

src/certkit/crl/Crl.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import kotlin.io.encoding.Base64
1111
import kotlin.time.Instant
1212

1313
/** Parses and builds X.509 Certificate Revocation Lists (CRLs). */
14-
object Crl {
14+
public object Crl {
1515

1616
private val CRL_PATTERN =
1717
"""-+BEGIN\s+X509\s+CRL[^-]*-+[\s\r\n]+([a-z0-9+/=\r\n]+)-+END\s+X509\s+CRL[^-]*-+"""
@@ -22,14 +22,14 @@ object Crl {
2222
private val certFactory = CertificateFactory.getInstance("X.509")
2323

2424
/** Parses an [X509CRL] from a PEM-encoded string. */
25-
fun from(pem: String): X509CRL {
25+
public fun from(pem: String): X509CRL {
2626
val match = CRL_PATTERN.find(pem) ?: error("No PEM-encoded CRL found")
2727
val der = Base64.Mime.decode(match.groupValues[1].encodeToByteArray())
2828
return certFactory.generateCRL(der.inputStream()) as X509CRL
2929
}
3030

3131
/** Parses an [X509CRL] from DER-encoded bytes. */
32-
fun from(bytes: ByteArray): X509CRL = certFactory.generateCRL(bytes.inputStream()) as X509CRL
32+
public fun from(bytes: ByteArray): X509CRL = certFactory.generateCRL(bytes.inputStream()) as X509CRL
3333

3434
/**
3535
* Builds a minimal X.509 CRL signed with SHA256withECDSA.
@@ -43,7 +43,7 @@ object Crl {
4343
* }
4444
* ```
4545
*/
46-
fun build(
46+
public fun build(
4747
keyPair: KeyPair,
4848
issuer: X500Principal,
4949
thisUpdate: Instant,
@@ -92,7 +92,7 @@ object Crl {
9292
* GeneralName ::= CHOICE { uniformResourceIdentifier [6] IA5String, ... }
9393
* ```
9494
*/
95-
fun distributionPoints(cert: X509Certificate): List<String> =
95+
public fun distributionPoints(cert: X509Certificate): List<String> =
9696
cert
9797
.getExtensionValue("2.5.29.31")
9898
?.let { unwrapOctetString(it) }

src/certkit/crl/Extns.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import java.security.cert.X509Certificate
55
import javax.naming.ldap.LdapName
66

77
/** Returns the issuer common name (CN) from the CRL's issuer distinguished name. */
8-
val X509CRL.issuerCN: String
8+
public val X509CRL.issuerCN: String
99
get() =
1010
LdapName(issuerX500Principal.name)
1111
.rdns
@@ -14,11 +14,11 @@ val X509CRL.issuerCN: String
1414
.single()
1515

1616
/** Returns `true` if this CRL was signed by the given [ca] certificate. */
17-
fun X509CRL.isSignedBy(ca: X509Certificate): Boolean =
17+
public fun X509CRL.isSignedBy(ca: X509Certificate): Boolean =
1818
issuerX500Principal == ca.subjectX500Principal && runCatching { verify(ca.publicKey) }.isSuccess
1919

2020
/** Returns `true` if the given [cert] is revoked in this CRL. */
21-
operator fun X509CRL.contains(cert: X509Certificate): Boolean = isRevoked(cert)
21+
public operator fun X509CRL.contains(cert: X509Certificate): Boolean = isRevoked(cert)
2222

2323
/** Returns `true` if this certificate is revoked per the given [crl]. */
24-
fun X509Certificate.isRevokedBy(crl: X509CRL): Boolean = crl.isRevoked(this)
24+
public fun X509Certificate.isRevokedBy(crl: X509CRL): Boolean = crl.isRevoked(this)

src/certkit/csr/Csr.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ import javax.security.auth.x500.X500Principal
1919
* }
2020
* ```
2121
*/
22-
object Csr {
22+
public object Csr {
2323

2424
private const val SIGNATURE_OID_PREFIX = "Alg.Alias.Signature.OID."
2525

2626
/** All signature algorithms discovered from JCA security providers, keyed by name. */
27-
val signatureAlgorithms: Map<String, SignatureAlgo> by lazy {
27+
public val signatureAlgorithms: Map<String, SignatureAlgo> by lazy {
2828
buildMap {
2929
Security.getProviders()
3030
.flatMap { it.entries }
@@ -38,7 +38,7 @@ object Csr {
3838
}
3939

4040
/** Creates a CSR from an X.500 name string, signing with the given [keyPair]. */
41-
fun create(
41+
public fun create(
4242
x500Name: String,
4343
algorithmName: String,
4444
keyPair: KeyPair,
@@ -51,7 +51,7 @@ object Csr {
5151
}
5252

5353
/** Creates a CSR by signing the given [info] with the [privateKey]. */
54-
fun create(info: CsrInfo, algorithm: SignatureAlgo, privateKey: PrivateKey): CsrRequest =
54+
public fun create(info: CsrInfo, algorithm: SignatureAlgo, privateKey: PrivateKey): CsrRequest =
5555
CsrRequest(info, algorithm, sign(info, algorithm, privateKey))
5656

5757
private fun sign(info: CsrInfo, algorithm: SignatureAlgo, privateKey: PrivateKey): ByteArray =

src/certkit/csr/CsrRequest.kt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,40 @@ import java.security.PublicKey
66
import javax.security.auth.x500.X500Principal
77

88
/** An immutable PKCS#10 Certificate Signing Request. */
9-
class CsrRequest(
10-
val info: CsrInfo,
11-
val algorithm: SignatureAlgo,
12-
val signature: ByteArray,
9+
public class CsrRequest(
10+
public val info: CsrInfo,
11+
public val algorithm: SignatureAlgo,
12+
public val signature: ByteArray,
1313
) {
14-
val encoded =
14+
public val encoded: ByteArray =
1515
Der.sequence(info.encoded, Der.sequence(algorithm.encoded), Der.bitString(0, signature))
1616

17-
override fun equals(other: Any?) =
17+
override fun equals(other: Any?): Boolean =
1818
this === other || (other is CsrRequest && encoded.contentEquals(other.encoded))
1919

20-
override fun hashCode() = encoded.contentHashCode()
20+
override fun hashCode(): Int = encoded.contentHashCode()
2121

22-
override fun toString() = "CsrRequest(info=$info, algorithm=$algorithm)"
22+
override fun toString(): String = "CsrRequest(info=$info, algorithm=$algorithm)"
2323
}
2424

2525
/**
2626
* Signature algorithm (name + OID) resolved from JCA security providers. Equality is by OID only.
2727
*/
28-
class SignatureAlgo(val name: String, val oid: String) {
29-
val encoded = Der.oid(oid)
28+
public class SignatureAlgo(public val name: String, public val oid: String) {
29+
public val encoded: ByteArray = Der.oid(oid)
3030

31-
override fun equals(other: Any?) = this === other || (other is SignatureAlgo && oid == other.oid)
31+
override fun equals(other: Any?): Boolean = this === other || (other is SignatureAlgo && oid == other.oid)
3232

33-
override fun hashCode() = oid.hashCode()
33+
override fun hashCode(): Int = oid.hashCode()
3434

35-
override fun toString() = "SignatureAlgo(name=$name, oid=$oid)"
35+
override fun toString(): String = "SignatureAlgo(name=$name, oid=$oid)"
3636
}
3737

3838
/** PKCS#10 CSR info: subject name + public key + optional SANs, DER-encoded per RFC 2986 §4.1. */
39-
data class CsrInfo(
40-
val subject: X500Principal,
41-
val publicKey: PublicKey,
42-
val sans: List<San> = emptyList(),
39+
public data class CsrInfo(
40+
public val subject: X500Principal,
41+
public val publicKey: PublicKey,
42+
public val sans: List<San> = emptyList(),
4343
) {
4444

4545
private companion object {
@@ -56,7 +56,7 @@ data class CsrInfo(
5656
const val SUBJECT_ALT_NAME_OID = "2.5.29.17"
5757
}
5858

59-
val encoded: ByteArray
59+
public val encoded: ByteArray
6060
get() =
6161
Der.sequence(
6262
VERSION_0,

0 commit comments

Comments
 (0)