@cap-kit/ssl-pinning 8.0.0-next.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/Package.swift +1 -1
  2. package/README.md +232 -372
  3. package/android/src/main/java/io/capkit/sslpinning/SSLPinningConfig.kt +48 -3
  4. package/android/src/main/java/io/capkit/sslpinning/SSLPinningError.kt +40 -0
  5. package/android/src/main/java/io/capkit/sslpinning/SSLPinningImpl.kt +137 -90
  6. package/android/src/main/java/io/capkit/sslpinning/SSLPinningPlugin.kt +146 -29
  7. package/android/src/main/java/io/capkit/sslpinning/utils/SSLPinningLogger.kt +30 -38
  8. package/android/src/main/java/io/capkit/sslpinning/utils/SSLPinningUtils.kt +25 -9
  9. package/dist/docs.json +29 -204
  10. package/dist/esm/definitions.d.ts +74 -177
  11. package/dist/esm/definitions.js +12 -6
  12. package/dist/esm/definitions.js.map +1 -1
  13. package/dist/esm/web.d.ts +9 -22
  14. package/dist/esm/web.js +5 -5
  15. package/dist/esm/web.js.map +1 -1
  16. package/dist/plugin.cjs.js +17 -11
  17. package/dist/plugin.cjs.js.map +1 -1
  18. package/dist/plugin.js +17 -11
  19. package/dist/plugin.js.map +1 -1
  20. package/ios/Sources/SSLPinningPlugin/SSLPinningConfig.swift +45 -30
  21. package/ios/Sources/SSLPinningPlugin/SSLPinningDelegate.swift +83 -26
  22. package/ios/Sources/SSLPinningPlugin/SSLPinningError.swift +49 -0
  23. package/ios/Sources/SSLPinningPlugin/SSLPinningImpl.swift +94 -64
  24. package/ios/Sources/SSLPinningPlugin/SSLPinningPlugin.swift +121 -50
  25. package/ios/Sources/SSLPinningPlugin/Utils/SSLPinningLogger.swift +28 -16
  26. package/ios/Sources/SSLPinningPlugin/Utils/SSLPinningUtils.swift +55 -18
  27. package/ios/Sources/SSLPinningPlugin/Version.swift +2 -2
  28. package/package.json +5 -6
package/README.md CHANGED
@@ -34,18 +34,61 @@
34
34
  ## Overview
35
35
 
36
36
  `@cap-kit/ssl-pinning` is a Capacitor plugin that performs **runtime SSL certificate
37
- verification** by validating the **SHA-256 fingerprint** of a server certificate.
37
+ fingerprint verification** on **iOS and Android** by validating the
38
+ **SHA-256 fingerprint** of a server certificate during the TLS handshake.
38
39
 
39
- The plugin works on **iOS and Android** and is designed to:
40
+ The plugin is designed to:
40
41
 
41
- - validate a single fingerprint (`checkCertificate`)
42
- - validate multiple fingerprints (`checkCertificates`)
42
+ - validate a single fingerprint using `checkCertificate`
43
+ - validate multiple fingerprints using `checkCertificates`
43
44
  - support configuration-based defaults via `capacitor.config.ts`
44
45
  - keep the JavaScript API platform-agnostic and stable
45
46
 
46
- This plugin **does not replace TLS** and **does not guarantee absolute security**.
47
- It enforces explicit trust decisions on top of standard TLS.
48
- It is a defense-in-depth mechanism that must be maintained correctly.
47
+ By enforcing explicit trust decisions, SSL pinning helps protect against
48
+ **man-in-the-middle attacks**.
49
+
50
+ This plugin performs **certificate pinning only**.
51
+ It does **not** expose full X.509 certificate inspection APIs at runtime,
52
+ does **not replace TLS**, and does **not guarantee absolute security**.
53
+
54
+ SSL pinning is a **defense-in-depth mechanism** and must be maintained correctly
55
+ over time.
56
+
57
+ ---
58
+
59
+ ## Platform Support
60
+
61
+ | Platform | Supported |
62
+ | -------- | --------- |
63
+ | iOS | ✅ |
64
+ | Android | ✅ |
65
+ | Web | ❌ |
66
+
67
+ On the Web, SSL certificate inspection is not possible due to browser security
68
+ restrictions. All methods will reject with an `Unimplemented` error.
69
+
70
+ ---
71
+
72
+ ## Future Directions (Informational)
73
+
74
+ In addition to runtime fingerprint-based SSL pinning, the long-term vision
75
+ for this plugin includes exploring additional trust models and configuration
76
+ strategies.
77
+
78
+ Potential future enhancements may include:
79
+
80
+ - **Loading trusted certificates from the application bundle**, for example
81
+ from a dedicated `certs/` directory, allowing certificate-based pinning
82
+ without hardcoding fingerprints.
83
+ - **Domain-based exclusions**, enabling developers to explicitly bypass
84
+ SSL pinning for selected hosts (e.g. analytics, third-party services, or
85
+ development environments).
86
+
87
+ These ideas are provided for informational purposes only.
88
+
89
+ They are **not part of the current API**, **not guaranteed to be implemented**,
90
+ and **may change or be discarded** based on platform constraints, security
91
+ considerations, and real-world usage feedback.
49
92
 
50
93
  ---
51
94
 
@@ -68,8 +111,11 @@ npx cap sync
68
111
  To use SSL pinning, you must obtain the **SHA-256 fingerprint**
69
112
  of the SSL certificate you intend to trust.
70
113
 
71
- Fingerprints can be generated using standard tools or via the
72
- companion CLI utility provided by this project.
114
+ A fingerprint is a cryptographic hash of the server certificate and is used
115
+ to uniquely identify it during the TLS handshake.
116
+
117
+ Fingerprints can be obtained using **standard tools** or via the
118
+ **built-in CLI utility provided by this project**.
73
119
 
74
120
  ---
75
121
 
@@ -78,14 +124,14 @@ companion CLI utility provided by this project.
78
124
  1. Open the target website in a modern browser.
79
125
  2. View the website certificate details.
80
126
  3. Export or copy the certificate (public key).
81
- 4. Use an online fingerprint generator, for example:
127
+ 4. Use a fingerprint generator, for example:
82
128
  https://www.samltool.com/fingerprint.php
83
129
  5. Select **SHA-256** as the algorithm.
84
- 6. Copy the resulting fingerprint (colon-separated format is acceptable).
130
+ 6. Copy the resulting fingerprint.
85
131
 
86
132
  ---
87
133
 
88
- ### Method 2 — Using the Command Line (OpenSSL)
134
+ ### Method 2 — Using OpenSSL
89
135
 
90
136
  If you have access to the certificate file (`.pem`, `.cer`, `.crt`):
91
137
 
@@ -103,12 +149,11 @@ SHA256 Fingerprint=EF:BA:26:D8:C1:CE:37:79:AC:77:63:0A:90:F8:21:63:A3:D6:89:2E:D
103
149
 
104
150
  ### Method 3 — Using the Built-in CLI Tool
105
151
 
106
- This project includes a CLI utility that can retrieve and display
107
- SSL certificate information for one or more domains.
152
+ This project includes a **command-line utility** that can retrieve
153
+ SSL certificates from remote servers and generate SHA-256 fingerprints.
108
154
 
109
- The CLI is intended as a **development and configuration helper**.
110
- It **does not perform SSL pinning** and does **not enforce trust decisions**
111
- at runtime.
155
+ The CLI is intended to be used **at development time**.
156
+ It **does not perform SSL pinning** and does **not make trust decisions at runtime**.
112
157
 
113
158
  Its purpose is to:
114
159
 
@@ -116,107 +161,62 @@ Its purpose is to:
116
161
  - extract SHA-256 fingerprints
117
162
  - assist in preparing configuration values for the runtime plugin
118
163
 
119
- ---
120
-
121
- #### Installation & Usage
122
-
123
- You don't need to install the tool globally. You can run it directly using your package manager if the plugin is installed in your project.
124
-
125
- **Using pnpm (Recommended):**
126
-
127
- ```bash
128
- pnpm exec ssl-fingerprint example.com
129
- ```
164
+ #### Basic usage
130
165
 
131
- **Using npx:**
166
+ > Note
167
+ > The CLI is exposed via the `cap-kit-ssl-pinning` command.
168
+ > Any internal script names shown in the help output (e.g. `fingerprint.js`)
169
+ > are implementation details and should not be invoked directly.
132
170
 
133
171
  ```bash
134
- npx ssl-fingerprint example.com
135
- ```
136
-
137
- If you prefer a global installation:
138
-
139
- ```bash
140
- npm install -g @cap-kit/ssl-pinning
141
- # or
142
- yarn global add @cap-kit/ssl-pinning
143
- # then run:
144
- ssl-fingerprint example.com
172
+ npx cap-kit-ssl-pinning example.com
145
173
  ```
146
174
 
147
- ---
148
-
149
- #### Usage
175
+ #### Multiple domains
150
176
 
151
177
  ```bash
152
- # Using npx
153
- npx ssl-fingerprint example.com
154
-
155
- # Multiple domains
156
- npx ssl-fingerprint example.com example.org example.net
157
-
158
- # If installed globally
159
- ssl-fingerprint example.com
178
+ npx cap-kit-ssl-pinning example.com api.example.com
160
179
  ```
161
180
 
162
- ---
163
-
164
181
  #### Modes
165
182
 
166
- The `--mode` flag controls how fingerprints are organized:
183
+ The `--mode` flag controls how fingerprints are grouped:
167
184
 
168
- - `--mode single`
185
+ - `single`
169
186
  Generates a single `fingerprint` value.
170
187
 
171
- - `--mode multi`
188
+ - `multi`
172
189
  Generates a `fingerprints[]` array (useful for certificate rotation).
173
190
 
174
- Example:
175
-
176
- ```bash
177
- npx ssl-fingerprint example.com api.example.com --mode multi
178
- ```
179
-
180
- ---
181
-
182
- You can also save the output to a file:
183
-
184
191
  ```bash
185
- ssl-fingerprint example.com --out certs.json
186
- ssl-fingerprint example.com example.org example.net --out certs.json
192
+ npx cap-kit-ssl-pinning example.com api.example.com --mode multi
187
193
  ```
188
194
 
189
- Generate output in TypeScript format (useful for configuration files):
195
+ > ⚠️ Note
196
+ >
197
+ > When using `--mode multi` with multiple domains, each domain is processed independently.
198
+ >
199
+ > If a certificate cannot be retrieved for a specific domain (e.g. DNS error or TLS failure),
200
+ > the error is reported in the output, but the CLI continues processing the remaining domains.
201
+ >
202
+ > The resulting `fingerprints` array will include **only successfully retrieved certificates**.
190
203
 
191
- ```bash
192
- ssl-fingerprint example.com --out fingerprints.ts --format fingerprints
193
- ```
194
-
195
- ---
196
-
197
- #### Formats
204
+ #### Output formats
198
205
 
199
206
  The `--format` flag controls the output structure:
200
207
 
201
- - `json`
202
- Raw certificate information (default)
203
-
204
- - `fingerprints`
205
- TypeScript array of fingerprints
206
-
207
- - `capacitor`
208
- Full `plugins` block for `capacitor.config.ts`
209
-
210
- - `capacitor-plugin`
211
- Only the `SSLPinning` plugin block
212
-
213
- - `capacitor-json`
214
- JSON equivalent of the Capacitor configuration
208
+ | Format | Description |
209
+ | ------------------ | ---------------------------------------------- |
210
+ | `json` | Full certificate information (default) |
211
+ | `fingerprints` | JavaScript array of fingerprints |
212
+ | `capacitor` | Full `plugins` block for `capacitor.config.ts` |
213
+ | `capacitor-plugin` | `SSLPinning` config block only |
214
+ | `capacitor-json` | JSON-compatible Capacitor configuration |
215
215
 
216
216
  Example:
217
217
 
218
218
  ```bash
219
- npx ssl-fingerprint example.com \
219
+ npx cap-kit-ssl-pinning example.com \
220
220
  --mode multi \
221
221
  --format capacitor
222
222
  ```
@@ -231,13 +231,40 @@ plugins: {
231
231
  }
232
232
  ```
233
233
 
234
+ Example (plugin block only):
235
+
236
+ ```bash
237
+ npx cap-kit-ssl-pinning example.com api.example.com \
238
+ --mode multi \
239
+ --format capacitor-plugin
240
+ ```
241
+
242
+ Output:
243
+
244
+ ```ts
245
+ SSLPinning: {
246
+ fingerprints: ['AA:BB:CC:DD:...', '11:22:33:44:...'];
247
+ }
248
+ ```
249
+
250
+ #### Insecure mode
251
+
252
+ By default, the CLI allows retrieving certificates even if the TLS
253
+ chain is invalid.
254
+
255
+ To enforce certificate validation:
256
+
257
+ ```bash
258
+ npx cap-kit-ssl-pinning example.com --insecure=false
259
+ ```
260
+
234
261
  ---
235
262
 
236
- #### Notes
263
+ ### Notes
237
264
 
238
265
  - Fingerprints are normalized internally by the runtime plugin.
239
266
  - Uppercase/lowercase differences are ignored.
240
- - Colons (`:`) are optional.
267
+ - Colon separators (`:`) are optional.
241
268
 
242
269
  The CLI **generates configuration**.
243
270
  The runtime plugin **consumes it**.
@@ -258,19 +285,25 @@ to production.
258
285
 
259
286
  ## Configuration
260
287
 
261
- The plugin supports static configuration via `capacitor.config.ts`.
262
- Configuration values are read **natively at runtime** and are not accessed from JavaScript.
288
+ Static configuration can be provided in `capacitor.config.ts` under
289
+ `plugins.SSLPinning`.
290
+
291
+ These values are:
292
+
293
+ - read natively at build/runtime
294
+ - not accessible from JavaScript at runtime
295
+ - treated as read-only fallback configuration
263
296
 
264
297
  <docgen-config>
265
298
  <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
266
299
 
267
300
  Configuration options for the SSLPinning plugin.
268
301
 
269
- | Prop | Type | Description | Default | Since |
270
- | -------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ------ |
271
- | **`verboseLogging`** | <code>boolean</code> | Enables detailed logging in the native console (Logcat/Xcode). Useful for debugging sensor data flow and lifecycle events. | <code>false</code> | 0.0.15 |
272
- | **`fingerprint`** | <code>string</code> | Default fingerprint used by checkCertificate() if no arguments are provided. | <code>undefined</code> | 0.0.14 |
273
- | **`fingerprints`** | <code>string[]</code> | Default fingerprints used by checkCertificates() if no arguments are provided. | <code>undefined</code> | 0.0.15 |
302
+ | Prop | Type | Description | Default | Since |
303
+ | -------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------ | ------ |
304
+ | **`verboseLogging`** | <code>boolean</code> | Enables verbose native logging (Logcat / Xcode console). | <code>false</code> | 0.0.15 |
305
+ | **`fingerprint`** | <code>string</code> | Default fingerprint used by `checkCertificate()` when `options.fingerprint` is not provided at runtime. | | 0.0.14 |
306
+ | **`fingerprints`** | <code>string[]</code> | Default fingerprints used by `checkCertificates()` when `options.fingerprints` is not provided at runtime. | | 0.0.15 |
274
307
 
275
308
  ### Examples
276
309
 
@@ -280,7 +313,7 @@ In `capacitor.config.json`:
280
313
  {
281
314
  "plugins": {
282
315
  "SSLPinning": {
283
- "verboseLogging": true,
316
+ "verboseLogging": false,
284
317
  "fingerprint": "50:4B:A1:B5:48:96:71:F3:9F:87:7E:0A:09:FD:3E:1B:C0:4F:AA:9F:FC:83:3E:A9:3A:00:78:88:F8:BA:60:26",
285
318
  "fingerprints": [
286
319
  "50:4B:A1:B5:48:96:71:F3:9F:87:7E:0A:09:FD:3E:1B:C0:4F:AA:9F:FC:83:3E:A9:3A:00:78:88:F8:BA:60:26"
@@ -300,7 +333,7 @@ import { CapacitorConfig } from '@capacitor/cli';
300
333
  const config: CapacitorConfig = {
301
334
  plugins: {
302
335
  SSLPinning: {
303
- verboseLogging: true,
336
+ verboseLogging: false,
304
337
  fingerprint: '50:4B:A1:B5:48:96:71:F3:9F:87:7E:0A:09:FD:3E:1B:C0:4F:AA:9F:FC:83:3E:A9:3A:00:78:88:F8:BA:60:26',
305
338
  fingerprints: ["50:4B:A1:B5:48:96:71:F3:9F:87:7E:0A:09:FD:3E:1B:C0:4F:AA:9F:FC:83:3E:A9:3A:00:78:88:F8:BA:60:26"],
306
339
  },
@@ -312,140 +345,14 @@ export default config;
312
345
 
313
346
  </docgen-config>
314
347
 
315
- ---
316
-
317
- ## 🔐 Pinning Mode (Runtime Behavior)
318
-
319
- This version of the plugin supports **fingerprint-based SSL pinning only**.
320
-
321
- ### How it works
322
-
323
- At runtime, the plugin:
324
-
325
- 1. Opens a TLS connection to the target HTTPS endpoint
326
- 2. Extracts the **leaf SSL certificate** presented by the server
327
- 3. Computes its **SHA-256 fingerprint**
328
- 4. Compares it against the expected fingerprint(s)
348
+ ### Configuration precedence
329
349
 
330
- The certificate is considered trusted if **any fingerprint matches**.
350
+ For each method call, fingerprint resolution follows this order:
331
351
 
332
- ---
333
-
334
- ### Supported pinning modes
352
+ 1. Runtime options passed from JavaScript
353
+ 2. Static configuration from `capacitor.config.ts`
335
354
 
336
- | Mode | Supported |
337
- | ------------------- | --------- |
338
- | Fingerprint pinning | ✅ Yes |
339
- | Certificate pinning | ❌ No |
340
- | Excluded domains | ❌ No |
341
-
342
- ---
343
-
344
- ## 🛡️ Security Model
345
-
346
- This plugin mitigates **man-in-the-middle (MITM) attacks**
347
- by enforcing explicit trust decisions at the TLS layer
348
- using certificate fingerprint validation.
349
-
350
- ### Security guarantees
351
-
352
- When correctly configured:
353
-
354
- - The connection is accepted **only if** the server certificate
355
- fingerprint matches one of the expected values.
356
- - Trust decisions are performed **natively at runtime**,
357
- outside of JavaScript control.
358
- - Certificate validation fails **closed** by default.
359
-
360
- ---
361
-
362
- ### Limitations
363
-
364
- This plugin intentionally:
365
-
366
- - Validates **only the leaf certificate**
367
- - Does **not** evaluate the full trust chain
368
- - Does **not** check certificate revocation (CRL / OCSP)
369
- - Does **not** protect against compromised application binaries
370
-
371
- It is a **defense-in-depth control** and must be combined
372
- with proper TLS configuration and backend security practices.
373
-
374
- ---
375
-
376
- ### Operational requirements
377
-
378
- Applications using this plugin must:
379
-
380
- - Monitor certificate expiration dates
381
- - Update fingerprints **before certificate rotation**
382
- - Test pinning behavior before production releases
383
-
384
- Incorrect configuration may result in **loss of connectivity** by design.
385
-
386
- ---
387
-
388
- ### Priority rules
389
-
390
- Fingerprint values are selected in the following order:
391
-
392
- 1. Fingerprints passed at runtime (`checkCertificate` / `checkCertificates`)
393
- 2. Fingerprints defined in `capacitor.config.ts`
394
-
395
- If no fingerprints are available, the operation fails.
396
-
397
- There is **no automatic fallback**.
398
-
399
- ---
400
-
401
- ## 🔧 Error Handling Model (Important)
402
-
403
- > ⚠️ **Read this before using `checkCertificate()` or `checkCertificates()`**
404
-
405
- This plugin uses a **state-based error model**, not exception-based errors.
406
-
407
- ### Why?
408
-
409
- - On **iOS (Capacitor 8 + Swift Package Manager)**, native Promise rejection
410
- is not reliably available.
411
- - To guarantee **cross-platform consistency**, the plugin always
412
- **resolves Promises** and returns an explicit result object.
413
-
414
- ### What this means
415
-
416
- - Promises are **never rejected** by the plugin.
417
- This behavior applies to **all platforms** to ensure API consistency.
418
- - Errors are reported as part of the resolved result.
419
- - Consumers must **always inspect the returned object**, not rely on `catch()`.
420
-
421
- ### Error fields
422
-
423
- When an error occurs, the result object may include:
424
-
425
- - `fingerprintMatched: false`
426
- - `error`: a human-readable diagnostic message
427
- - `errorCode`: a standardized error identifier
428
-
429
- Example:
430
-
431
- ```ts
432
- const result = await SSLPinning.checkCertificate();
433
-
434
- if (!result.fingerprintMatched) {
435
- console.error(result.error, result.errorCode);
436
- }
437
- ```
438
-
439
- ### Standardized error codes
440
-
441
- The `errorCode` field (when present) is one of the following:
442
-
443
- - `UNAVAILABLE` – the feature is not available at runtime
444
- - `PERMISSION_DENIED` – access was denied by the system or configuration
445
- - `INIT_FAILED` – initialization or runtime failure occurred
446
- - `UNKNOWN_TYPE` – unsupported or invalid pinning configuration
447
-
448
- These codes are intended for **programmatic handling**, not for user-facing messages.
355
+ If no fingerprint is available from either source, the call will fail.
449
356
 
450
357
  ---
451
358
 
@@ -453,9 +360,7 @@ These codes are intended for **programmatic handling**, not for user-facing mess
453
360
 
454
361
  <docgen-index>
455
362
 
456
- * [`checkCertificate()`](#checkcertificate)
457
363
  * [`checkCertificate(...)`](#checkcertificate)
458
- * [`checkCertificates()`](#checkcertificates)
459
364
  * [`checkCertificates(...)`](#checkcertificates)
460
365
  * [`getPluginVersion()`](#getpluginversion)
461
366
  * [Interfaces](#interfaces)
@@ -465,38 +370,7 @@ These codes are intended for **programmatic handling**, not for user-facing mess
465
370
  <docgen-api>
466
371
  <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
467
372
 
468
- Interface defining the structure of an SSL Certificate Checker Plugin.
469
-
470
- Implementations of this interface should provide the logic for checking
471
- the status and details of an SSL certificate based on the provided options.
472
-
473
- ### checkCertificate()
474
-
475
- ```typescript
476
- checkCertificate() => Promise<SSLPinningResult>
477
- ```
478
-
479
- Check the SSL certificate of a server.
480
-
481
- **Returns:** <code>Promise&lt;<a href="#sslpinningresult">SSLPinningResult</a>&gt;</code>
482
-
483
- **Since:** 0.0.14
484
-
485
- #### Example
486
-
487
- ```typescript
488
- import { SSLPinning } from '@cap-kit/ssl-pinning';
489
-
490
- const result = await SSLPinning.checkCertificate({
491
- url: 'https://example.com',
492
- fingerprint: '50:4B:A1:B5:48:96:71:F3:9F:87:7E:0A:09:FD:3E:1B:C0:4F:AA:9F:FC:83:3E:A9:3A:00:78:88:F8:BA:60:26'
493
- });
494
-
495
- console.log('SSL Pinning Result:', result);
496
- ```
497
-
498
- --------------------
499
-
373
+ SSL Pinning Capacitor Plugin interface.
500
374
 
501
375
  ### checkCertificate(...)
502
376
 
@@ -504,96 +378,35 @@ console.log('SSL Pinning Result:', result);
504
378
  checkCertificate(options: SSLPinningOptions) => Promise<SSLPinningResult>
505
379
  ```
506
380
 
507
- Check the SSL certificate of a server.
381
+ Checks the SSL certificate of a server using a single fingerprint.
508
382
 
509
- | Param | Type | Description |
510
- | ------------- | --------------------------------------------------------------- | ------------------------------------------- |
511
- | **`options`** | <code><a href="#sslpinningoptions">SSLPinningOptions</a></code> | - Options for checking the SSL certificate. |
383
+ | Param | Type |
384
+ | ------------- | --------------------------------------------------------------- |
385
+ | **`options`** | <code><a href="#sslpinningoptions">SSLPinningOptions</a></code> |
512
386
 
513
387
  **Returns:** <code>Promise&lt;<a href="#sslpinningresult">SSLPinningResult</a>&gt;</code>
514
388
 
515
389
  **Since:** 0.0.14
516
390
 
517
- #### Example
518
-
519
- ```typescript
520
- import { SSLPinning } from '@cap-kit/ssl-pinning';
521
-
522
- const result = await SSLPinning.checkCertificate({
523
- url: 'https://example.com',
524
- fingerprint: '50:4B:A1:B5:48:96:71:F3:9F:87:7E:0A:09:FD:3E:1B:C0:4F:AA:9F:FC:83:3E:A9:3A:00:78:88:F8:BA:60:26'
525
- });
526
-
527
- console.log('SSL Pinning Result:', result);
528
- ```
529
-
530
- --------------------
531
-
532
-
533
- ### checkCertificates()
534
-
535
- ```typescript
536
- checkCertificates() => Promise<SSLPinningResult[]>
537
- ```
538
-
539
- Check the SSL certificates of multiple servers.
540
-
541
- **Returns:** <code>Promise&lt;SSLPinningResult[]&gt;</code>
542
-
543
- **Since:** 0.0.15
544
-
545
- #### Example
546
-
547
- ```typescript
548
- import { SSLPinning } from '@cap-kit/ssl-pinning';
549
-
550
- const results = await SSLPinning.checkCertificates();
551
-
552
- results.forEach(result => {
553
- console.log('SSL Pinning Result:', result);
554
- });
555
- ```
556
-
557
391
  --------------------
558
392
 
559
393
 
560
394
  ### checkCertificates(...)
561
395
 
562
396
  ```typescript
563
- checkCertificates(options: SSLPinningMultiOptions[]) => Promise<SSLPinningResult[]>
397
+ checkCertificates(options: SSLPinningMultiOptions) => Promise<SSLPinningResult>
564
398
  ```
565
399
 
566
- Check the SSL certificates of multiple servers.
400
+ Checks the SSL certificate of a server using multiple allowed fingerprints.
567
401
 
568
- | Param | Type | Description |
569
- | ------------- | ------------------------------------- | -------------------------------------------- |
570
- | **`options`** | <code>SSLPinningMultiOptions[]</code> | - Options for checking the SSL certificates. |
402
+ | Param | Type |
403
+ | ------------- | ------------------------------------------------------------------------- |
404
+ | **`options`** | <code><a href="#sslpinningmultioptions">SSLPinningMultiOptions</a></code> |
571
405
 
572
- **Returns:** <code>Promise&lt;SSLPinningResult[]&gt;</code>
406
+ **Returns:** <code>Promise&lt;<a href="#sslpinningresult">SSLPinningResult</a>&gt;</code>
573
407
 
574
408
  **Since:** 0.0.15
575
409
 
576
- #### Example
577
-
578
- ```typescript
579
- import { SSLPinning } from '@cap-kit/ssl-pinning';
580
-
581
- const results = await SSLPinning.checkCertificates([
582
- {
583
- url: 'https://example.com',
584
- fingerprints: ['50:4B:A1:B5:48:96:71:F3:9F:87:7E:0A:09:FD:3E:1B:C0:4F:AA:9F:FC:83:3E:A9:3A:00:78:88:F8:BA:60:26']
585
- },
586
- {
587
- url: 'https://another-example.com',
588
- fingerprints: ['AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90']
589
- }
590
- ]);
591
-
592
- results.forEach(result => {
593
- console.log('SSL Pinning Result:', result);
594
- });
595
- ```
596
-
597
410
  --------------------
598
411
 
599
412
 
@@ -626,43 +439,36 @@ const { version } = await SSLPinning.getPluginVersion();
626
439
 
627
440
  #### SSLPinningResult
628
441
 
629
- Result returned by the SSL certificate check.
442
+ Result returned by a successful SSL certificate check.
630
443
 
631
- NOTE:
632
- On iOS (Swift Package Manager), errors are returned
633
- as part of the resolved result object rather than
634
- Promise rejections.
444
+ This object is returned ONLY on success.
445
+ Failures are delivered via Promise rejection.
635
446
 
636
- | Prop | Type | Description |
637
- | ------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
638
- | **`subject`** | <code>string</code> | The subject of the certificate, representing the entity the certificate is issued to. |
639
- | **`issuer`** | <code>string</code> | The issuer of the certificate, indicating the certificate authority that issued it. Results may vary slightly between iOS and Android platforms. |
640
- | **`validFrom`** | <code>string</code> | The start date from which the certificate is valid. Format: ISO 8601 string or platform-specific date representation. |
641
- | **`validTo`** | <code>string</code> | The end date until which the certificate is valid. Format: ISO 8601 string or platform-specific date representation. |
642
- | **`expectedFingerprint`** | <code>string</code> | The fingerprint that is expected to match the certificate's actual fingerprint. This is typically provided in the <a href="#sslpinningoptions">SSLPinningOptions</a>. |
643
- | **`actualFingerprint`** | <code>string</code> | The actual fingerprint of the SSL certificate retrieved from the server. |
644
- | **`fingerprintMatched`** | <code>boolean</code> | Indicates whether the actual fingerprint matches the expected fingerprint. `true` if they match, `false` otherwise. |
645
- | **`error`** | <code>string</code> | A descriptive error message if an issue occurred during the SSL certificate check. |
447
+ | Prop | Type | Description |
448
+ | ------------------------ | -------------------- | ------------------------------------------------------ |
449
+ | **`actualFingerprint`** | <code>string</code> | Actual SHA-256 fingerprint of the server certificate. |
450
+ | **`fingerprintMatched`** | <code>boolean</code> | Indicates whether the certificate fingerprint matched. |
451
+ | **`matchedFingerprint`** | <code>string</code> | The fingerprint that successfully matched, if any. |
646
452
 
647
453
 
648
454
  #### SSLPinningOptions
649
455
 
650
456
  Options for checking a single SSL certificate.
651
457
 
652
- | Prop | Type | Description |
653
- | ----------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------- |
654
- | **`url`** | <code>string</code> | The URL of the server whose SSL certificate needs to be checked. |
655
- | **`fingerprint`** | <code>string</code> | The expected fingerprint of the SSL certificate to validate against. This is typically a hash string such as SHA-256. |
458
+ | Prop | Type | Description |
459
+ | ----------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
460
+ | **`url`** | <code>string</code> | HTTPS URL of the server whose SSL certificate must be checked. This value is REQUIRED and cannot be provided via configuration. |
461
+ | **`fingerprint`** | <code>string</code> | Expected SHA-256 fingerprint of the certificate. Resolution order: 1. `options.fingerprint` (runtime) 2. `plugins.SSLPinning.fingerprint` (config) If neither is provided, the Promise is rejected with `SSLPinningErrorCode.UNAVAILABLE`. |
656
462
 
657
463
 
658
464
  #### SSLPinningMultiOptions
659
465
 
660
- Options for checking multiple SSL certificates.
466
+ Options for checking an SSL certificate using multiple allowed fingerprints.
661
467
 
662
- | Prop | Type | Description |
663
- | ------------------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
664
- | **`url`** | <code>string</code> | The URL of the server whose SSL certificate needs to be checked. |
665
- | **`fingerprints`** | <code>string[]</code> | The expected fingerprints of the SSL certificate to validate against. This is typically an array of hash strings such as SHA-256. |
468
+ | Prop | Type | Description |
469
+ | ------------------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
470
+ | **`url`** | <code>string</code> | HTTPS URL of the server whose SSL certificate must be checked. This value is REQUIRED and cannot be provided via configuration. |
471
+ | **`fingerprints`** | <code>string[]</code> | Expected SHA-256 fingerprints of the certificate. Resolution order: 1. `options.fingerprints` (runtime) 2. `plugins.SSLPinning.fingerprints` (config) If neither is provided, the Promise is rejected with `SSLPinningErrorCode.UNAVAILABLE`. |
666
472
 
667
473
 
668
474
  #### PluginVersionResult
@@ -679,7 +485,7 @@ Result returned by the getPluginVersion method.
679
485
 
680
486
  ## Usage
681
487
 
682
- ### Single fingerprint
488
+ ### Single fingerprint check
683
489
 
684
490
  ```ts
685
491
  import { SSLPinning } from '@cap-kit/ssl-pinning';
@@ -690,34 +496,88 @@ const result = await SSLPinning.checkCertificate({
690
496
  });
691
497
 
692
498
  if (result.fingerprintMatched) {
693
- // Certificate is trusted
499
+ console.log('Certificate is trusted');
694
500
  }
695
501
  ```
696
502
 
697
- ### Multiple fingerprints
503
+ ### Multiple fingerprint check
698
504
 
699
505
  ```ts
506
+ import { SSLPinning } from '@cap-kit/ssl-pinning';
507
+
700
508
  const result = await SSLPinning.checkCertificates({
701
509
  url: 'https://example.com',
702
510
  fingerprints: ['AA:BB:CC:DD:...', '11:22:33:44:...'],
703
511
  });
704
512
 
705
513
  if (result.fingerprintMatched) {
706
- // At least one fingerprint matched
514
+ console.log('Certificate matched:', result.matchedFingerprint);
707
515
  }
708
516
  ```
709
517
 
710
- When no fingerprints are passed at runtime, the plugin will use the values
711
- defined in `capacitor.config.ts`.
518
+ ---
519
+
520
+ ## Result Object
521
+
522
+ On success, the Promise resolves with the following object:
523
+
524
+ ```ts
525
+ interface SSLPinningResult {
526
+ actualFingerprint: string;
527
+ fingerprintMatched: boolean;
528
+ matchedFingerprint?: string;
529
+ }
530
+ ```
531
+
532
+ ---
533
+
534
+ ## Error Handling Model (Important)
535
+
536
+ This plugin uses a **Promise rejection–based error model**.
537
+
538
+ - Successful calls always resolve with `SSLPinningResult`
539
+ - Failures always reject with `CapacitorException`
540
+ - Error codes are exposed via `err.code`
541
+
542
+ ### Example
543
+
544
+ ```ts
545
+ import { SSLPinning, SSLPinningErrorCode } from '@cap-kit/ssl-pinning';
546
+
547
+ try {
548
+ await SSLPinning.checkCertificate({
549
+ url: 'https://example.com',
550
+ });
551
+ } catch (err: any) {
552
+ if (err.code === SSLPinningErrorCode.UNAVAILABLE) {
553
+ console.error('No fingerprint provided');
554
+ } else {
555
+ console.error('SSL pinning failed', err);
556
+ }
557
+ }
558
+ ```
559
+
560
+ ### Error codes
561
+
562
+ | Code | Description |
563
+ | ------------------- | ------------------------------------------- |
564
+ | `UNAVAILABLE` | No fingerprint provided (runtime or config) |
565
+ | `PERMISSION_DENIED` | Required permission denied |
566
+ | `INIT_FAILED` | Runtime or initialization failure |
567
+ | `UNKNOWN_TYPE` | Invalid or unsupported input |
712
568
 
713
569
  ---
714
570
 
715
571
  ## Security Notes
716
572
 
717
- - SSL pinning **requires maintenance**. Expired or rotated certificates
718
- must be updated before they become invalid.
719
- - Incorrect configuration can result in **loss of connectivity**.
720
- - SSL pinning may interfere with debugging tools and traffic inspection.
573
+ - Only HTTPS URLs are accepted.
574
+ - The system trust chain is **not** evaluated.
575
+ - Certificate acceptance is based **solely on fingerprint matching**.
576
+
577
+ - SSL pinning **requires ongoing maintenance**.
578
+ Certificates that expire or are rotated **must be updated** before they become invalid.
579
+ - Incorrect configuration may result in **loss of network connectivity**.
580
+ - SSL pinning can interfere with debugging tools and HTTPS traffic inspection.
721
581
  - This plugin is provided **as-is**, without warranty.
722
582
 
723
583
  Always test thoroughly in your target environment.