Skip to content

Commit bbbb161

Browse files
committed
Documentation, naming, and code style cleanup
Add KDoc to all public APIs. Convert test code to idiomatic .use{} blocks. Add @JvmStatic and @serializable annotations where missing. Align signing server property names with Kotlin conventions.
1 parent 1405f38 commit bbbb161

23 files changed

Lines changed: 691 additions & 661 deletions

File tree

example-app/app/src/main/kotlin/org/contentauth/c2pa/exampleapp/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
This file is licensed to you under the Apache License, Version 2.0
33
(http://www.apache.org/licenses/LICENSE-2.0) or the MIT license
44
(http://opensource.org/licenses/MIT), at your option.

library/src/androidTest/kotlin/org/contentauth/c2pa/AndroidCoreTests.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
This file is licensed to you under the Apache License, Version 2.0
33
(http://www.apache.org/licenses/LICENSE-2.0) or the MIT license
44
(http://opensource.org/licenses/MIT), at your option.
@@ -9,6 +9,7 @@ ANY KIND, either express or implied. See the LICENSE-MIT and LICENSE-APACHE
99
files for the specific language governing permissions and limitations under
1010
each license.
1111
*/
12+
1213
package org.contentauth.c2pa
1314

1415
import android.content.Context

library/src/androidTest/kotlin/org/contentauth/c2pa/AndroidSignerTests.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ANY KIND, either express or implied. See the LICENSE-MIT and LICENSE-APACHE
99
files for the specific language governing permissions and limitations under
1010
each license.
1111
*/
12+
1213
package org.contentauth.c2pa
1314

1415
import android.content.Context

library/src/androidTest/kotlin/org/contentauth/c2pa/AndroidStreamTests.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
This file is licensed to you under the Apache License, Version 2.0
33
(http://www.apache.org/licenses/LICENSE-2.0) or the MIT license
44
(http://opensource.org/licenses/MIT), at your option.
@@ -9,6 +9,7 @@ ANY KIND, either express or implied. See the LICENSE-MIT and LICENSE-APACHE
99
files for the specific language governing permissions and limitations under
1010
each license.
1111
*/
12+
1213
package org.contentauth.c2pa
1314

1415
import android.content.Context

library/src/androidTest/kotlin/org/contentauth/c2pa/AndroidWebServiceTests.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
This file is licensed to you under the Apache License, Version 2.0
33
(http://www.apache.org/licenses/LICENSE-2.0) or the MIT license
44
(http://opensource.org/licenses/MIT), at your option.
@@ -9,6 +9,7 @@ ANY KIND, either express or implied. See the LICENSE-MIT and LICENSE-APACHE
99
files for the specific language governing permissions and limitations under
1010
each license.
1111
*/
12+
1213
package org.contentauth.c2pa
1314

1415
import android.content.Context

library/src/main/kotlin/org/contentauth/c2pa/C2PAError.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
This file is licensed to you under the Apache License, Version 2.0
33
(http://www.apache.org/licenses/LICENSE-2.0) or the MIT license
44
(http://opensource.org/licenses/MIT), at your option.
@@ -13,21 +13,29 @@ each license.
1313
package org.contentauth.c2pa
1414

1515
/**
16-
* Error model for C2PA operations
16+
* Sealed error hierarchy for C2PA operations.
17+
*
18+
* All errors thrown by the C2PA library are subtypes of this class, allowing
19+
* callers to handle them with exhaustive `when` expressions.
1720
*/
1821
sealed class C2PAError : Exception() {
22+
23+
/** An error returned by the native C2PA API with a descriptive message. */
1924
data class Api(override val message: String) : C2PAError() {
2025
override fun toString() = "C2PA-API error: $message"
2126
}
2227

28+
/** A null pointer was unexpectedly returned from the native layer. */
2329
object NilPointer : C2PAError() {
2430
override fun toString() = "Unexpected NULL pointer"
2531
}
2632

33+
/** A UTF-8 conversion error occurred when reading native string data. */
2734
object Utf8 : C2PAError() {
2835
override fun toString() = "Invalid UTF-8 from C2PA"
2936
}
3037

38+
/** A negative status code was returned from a native operation. */
3139
data class Negative(val value: Long) : C2PAError() {
3240
override fun toString() = "C2PA negative status $value"
3341
}

library/src/main/kotlin/org/contentauth/c2pa/Helpers.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
This file is licensed to you under the Apache License, Version 2.0
33
(http://www.apache.org/licenses/LICENSE-2.0) or the MIT license
44
(http://opensource.org/licenses/MIT), at your option.
@@ -91,5 +91,5 @@ fun derToRawSignature(derSignature: ByteArray, componentLength: Int): ByteArray
9191
return rPadded + sPadded
9292
}
9393

94-
/** C2PA version fetched once */
94+
/** The version string of the native C2PA library, lazily fetched once on first access. */
9595
val c2paVersion: String by lazy { C2PA.version() }

library/src/main/kotlin/org/contentauth/c2pa/KeyStoreSigner.kt

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
This file is licensed to you under the Apache License, Version 2.0
33
(http://www.apache.org/licenses/LICENSE-2.0) or the MIT license
44
(http://opensource.org/licenses/MIT), at your option.
@@ -61,6 +61,7 @@ object KeyStoreSigner {
6161
* @param tsaURL Optional timestamp authority URL
6262
* @return A configured Signer instance
6363
*/
64+
@JvmStatic
6465
fun createSigner(
6566
algorithm: SigningAlgorithm,
6667
certificateChainPEM: String,
@@ -100,6 +101,7 @@ object KeyStoreSigner {
100101
* @param promptDescription Description for the biometric prompt
101102
* @return A configured Signer instance after successful authentication
102103
*/
104+
@JvmStatic
103105
suspend fun createBiometricSigner(
104106
activity: FragmentActivity,
105107
keyAlias: String,
@@ -162,6 +164,7 @@ object KeyStoreSigner {
162164
*
163165
* @return true if hardware-backed KeyStore is available
164166
*/
167+
@JvmStatic
165168
fun isHardwareBackedKeystoreAvailable(): Boolean = try {
166169
KeyStore.getInstance("AndroidKeyStore").load(null)
167170
true
@@ -175,10 +178,13 @@ object KeyStoreSigner {
175178
* @param keyAlias The alias of the key to check
176179
* @return true if the key is hardware-backed
177180
*/
178-
fun isKeyHardwareBacked(keyAlias: String): Boolean {
179-
return try {
180-
val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
181-
val privateKey = keyStore.getKey(keyAlias, null) as? PrivateKey ?: return false
181+
@JvmStatic
182+
fun isKeyHardwareBacked(keyAlias: String): Boolean = try {
183+
val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
184+
val privateKey = keyStore.getKey(keyAlias, null) as? PrivateKey
185+
if (privateKey == null) {
186+
false
187+
} else {
182188
val keyInfo =
183189
KeyFactory.getInstance(privateKey.algorithm, "AndroidKeyStore")
184190
.getKeySpec(privateKey, KeyInfo::class.java)
@@ -188,9 +194,9 @@ object KeyStoreSigner {
188194
@Suppress("DEPRECATION")
189195
keyInfo.isInsideSecureHardware
190196
}
191-
} catch (e: Exception) {
192-
false
193197
}
198+
} catch (e: Exception) {
199+
false
194200
}
195201

196202
/**
@@ -199,6 +205,7 @@ object KeyStoreSigner {
199205
* @param keyAlias The alias of the key to check
200206
* @return true if the key exists
201207
*/
208+
@JvmStatic
202209
fun keyExists(keyAlias: String): Boolean = try {
203210
val keyStore = KeyStore.getInstance("AndroidKeyStore")
204211
keyStore.load(null)
@@ -213,6 +220,7 @@ object KeyStoreSigner {
213220
* @param keyAlias The alias of the key to delete
214221
* @return true if the key was deleted or didn't exist
215222
*/
223+
@JvmStatic
216224
fun deleteKey(keyAlias: String): Boolean = try {
217225
val keyStore = KeyStore.getInstance("AndroidKeyStore")
218226
keyStore.load(null)

library/src/main/kotlin/org/contentauth/c2pa/Signer.kt

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,19 @@ class Signer internal constructor(internal var ptr: Long) : Closeable {
2727
loadC2PALibraries()
2828
}
2929

30-
/** Create signer from certificates and private key */
30+
/**
31+
* Creates a signer from PEM-encoded certificates and a private key.
32+
*
33+
* This is the simplest way to create a signer when you have the certificate chain
34+
* and private key available as PEM strings.
35+
*
36+
* @param certsPEM The certificate chain in PEM format
37+
* @param privateKeyPEM The private key in PEM format
38+
* @param algorithm The [SigningAlgorithm] to use (e.g., ES256, ES384)
39+
* @param tsaURL Optional timestamp authority URL for trusted timestamping
40+
* @return A configured [Signer] instance
41+
* @throws C2PAError.Api if the certificates or key are invalid
42+
*/
3143
@JvmStatic
3244
@Throws(C2PAError::class)
3345
fun fromKeys(
@@ -40,7 +52,13 @@ class Signer internal constructor(internal var ptr: Long) : Closeable {
4052
return fromInfo(info)
4153
}
4254

43-
/** Create signer from SignerInfo */
55+
/**
56+
* Creates a signer from a [SignerInfo] configuration object.
57+
*
58+
* @param info The [SignerInfo] containing algorithm, certificates, key, and TSA URL
59+
* @return A configured [Signer] instance
60+
* @throws C2PAError.Api if the signer cannot be created from the provided info
61+
*/
4462
@JvmStatic
4563
@Throws(C2PAError::class)
4664
fun fromInfo(info: SignerInfo): Signer = executeC2PAOperation("Failed to create signer") {
@@ -180,7 +198,23 @@ class Signer internal constructor(internal var ptr: Long) : Closeable {
180198
}
181199
}
182200

183-
/** Create signer with custom signing callback */
201+
/**
202+
* Creates a signer with a custom signing callback.
203+
*
204+
* Use this when the signing operation is handled externally, such as with
205+
* hardware security modules (StrongBox, Android Keystore) or remote signing
206+
* services. The callback receives raw bytes to sign and must return the signature.
207+
*
208+
* @param algorithm The [SigningAlgorithm] to use
209+
* @param certificateChainPEM The certificate chain in PEM format
210+
* @param tsaURL Optional timestamp authority URL for trusted timestamping
211+
* @param sign Callback that receives data bytes and returns the signature bytes
212+
* @return A configured [Signer] instance
213+
* @throws C2PAError.Api if the callback signer cannot be created
214+
*
215+
* @see StrongBoxSigner
216+
* @see KeyStoreSigner
217+
*/
184218
@JvmStatic
185219
@Throws(C2PAError::class)
186220
fun withCallback(

library/src/main/kotlin/org/contentauth/c2pa/SignerInfo.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
This file is licensed to you under the Apache License, Version 2.0
33
(http://www.apache.org/licenses/LICENSE-2.0) or the MIT license
44
(http://opensource.org/licenses/MIT), at your option.
@@ -13,7 +13,15 @@ each license.
1313
package org.contentauth.c2pa
1414

1515
/**
16-
* Signer information
16+
* Configuration for creating a [Signer] from PEM-encoded credentials.
17+
*
18+
* @property algorithm The [SigningAlgorithm] to use (e.g., ES256, PS256)
19+
* @property certificatePEM The certificate chain in PEM format
20+
* @property privateKeyPEM The private key in PEM format
21+
* @property tsaURL Optional timestamp authority URL for trusted timestamping
22+
*
23+
* @see Signer.fromInfo
24+
* @see Signer.fromKeys
1725
*/
1826
data class SignerInfo(
1927
val algorithm: SigningAlgorithm,

0 commit comments

Comments
 (0)