@capgo/capacitor-updater 6.14.0 → 6.14.2

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 (30) hide show
  1. package/README.md +11 -11
  2. package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +134 -194
  3. package/android/src/main/java/ee/forgr/capacitor_updater/BundleStatus.java +23 -23
  4. package/android/src/main/java/ee/forgr/capacitor_updater/Callback.java +1 -1
  5. package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdater.java +960 -1165
  6. package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1259 -1629
  7. package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipher.java +161 -197
  8. package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipherV2.java +202 -256
  9. package/android/src/main/java/ee/forgr/capacitor_updater/DataManager.java +16 -16
  10. package/android/src/main/java/ee/forgr/capacitor_updater/DelayCondition.java +44 -48
  11. package/android/src/main/java/ee/forgr/capacitor_updater/DelayUntilNext.java +4 -4
  12. package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +378 -467
  13. package/android/src/main/java/ee/forgr/capacitor_updater/DownloadWorkerManager.java +71 -83
  14. package/android/src/main/java/ee/forgr/capacitor_updater/InternalUtils.java +19 -28
  15. package/dist/docs.json +17 -17
  16. package/dist/esm/definitions.d.ts +13 -13
  17. package/dist/esm/definitions.js.map +1 -1
  18. package/dist/esm/index.d.ts +2 -2
  19. package/dist/esm/index.js +4 -4
  20. package/dist/esm/index.js.map +1 -1
  21. package/dist/esm/web.d.ts +2 -2
  22. package/dist/esm/web.js +43 -43
  23. package/dist/esm/web.js.map +1 -1
  24. package/dist/plugin.cjs.js +43 -43
  25. package/dist/plugin.cjs.js.map +1 -1
  26. package/dist/plugin.js +43 -43
  27. package/dist/plugin.js.map +1 -1
  28. package/ios/Plugin/CapacitorUpdater.swift +8 -8
  29. package/ios/Plugin/CapacitorUpdaterPlugin.swift +1 -1
  30. package/package.json +5 -7
@@ -43,208 +43,172 @@ import javax.crypto.spec.SecretKeySpec;
43
43
 
44
44
  public class CryptoCipher {
45
45
 
46
- public static byte[] decryptRSA(byte[] source, PrivateKey privateKey)
47
- throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
48
- Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
49
- OAEPParameterSpec oaepParams = new OAEPParameterSpec(
50
- "SHA-256",
51
- "MGF1",
52
- new MGF1ParameterSpec("SHA-256"),
53
- PSource.PSpecified.DEFAULT
54
- );
55
- cipher.init(Cipher.DECRYPT_MODE, privateKey, oaepParams);
56
- return cipher.doFinal(source);
57
- }
58
-
59
- public static byte[] decryptAES(byte[] cipherText, SecretKey key, byte[] iv) {
60
- try {
61
- IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
62
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
63
- SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
64
- cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
65
- return cipher.doFinal(cipherText);
66
- } catch (Exception e) {
67
- e.printStackTrace();
46
+ public static byte[] decryptRSA(byte[] source, PrivateKey privateKey)
47
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
48
+ Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
49
+ OAEPParameterSpec oaepParams = new OAEPParameterSpec(
50
+ "SHA-256",
51
+ "MGF1",
52
+ new MGF1ParameterSpec("SHA-256"),
53
+ PSource.PSpecified.DEFAULT
54
+ );
55
+ cipher.init(Cipher.DECRYPT_MODE, privateKey, oaepParams);
56
+ return cipher.doFinal(source);
68
57
  }
69
- return null;
70
- }
71
-
72
- public static SecretKey byteToSessionKey(byte[] sessionKey) {
73
- // rebuild key using SecretKeySpec
74
- return new SecretKeySpec(sessionKey, 0, sessionKey.length, "AES");
75
- }
76
-
77
- private static PrivateKey readPkcs8PrivateKey(byte[] pkcs8Bytes)
78
- throws GeneralSecurityException {
79
- KeyFactory keyFactory = KeyFactory.getInstance("RSA");
80
- PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8Bytes);
81
- try {
82
- return keyFactory.generatePrivate(keySpec);
83
- } catch (InvalidKeySpecException e) {
84
- throw new IllegalArgumentException("Unexpected key format!", e);
58
+
59
+ public static byte[] decryptAES(byte[] cipherText, SecretKey key, byte[] iv) {
60
+ try {
61
+ IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
62
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
63
+ SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
64
+ cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
65
+ return cipher.doFinal(cipherText);
66
+ } catch (Exception e) {
67
+ e.printStackTrace();
68
+ }
69
+ return null;
70
+ }
71
+
72
+ public static SecretKey byteToSessionKey(byte[] sessionKey) {
73
+ // rebuild key using SecretKeySpec
74
+ return new SecretKeySpec(sessionKey, 0, sessionKey.length, "AES");
75
+ }
76
+
77
+ private static PrivateKey readPkcs8PrivateKey(byte[] pkcs8Bytes) throws GeneralSecurityException {
78
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
79
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8Bytes);
80
+ try {
81
+ return keyFactory.generatePrivate(keySpec);
82
+ } catch (InvalidKeySpecException e) {
83
+ throw new IllegalArgumentException("Unexpected key format!", e);
84
+ }
85
+ }
86
+
87
+ private static byte[] join(byte[] byteArray1, byte[] byteArray2) {
88
+ byte[] bytes = new byte[byteArray1.length + byteArray2.length];
89
+ System.arraycopy(byteArray1, 0, bytes, 0, byteArray1.length);
90
+ System.arraycopy(byteArray2, 0, bytes, byteArray1.length, byteArray2.length);
91
+ return bytes;
92
+ }
93
+
94
+ private static PrivateKey readPkcs1PrivateKey(byte[] pkcs1Bytes) throws GeneralSecurityException {
95
+ // We can't use Java internal APIs to parse ASN.1 structures, so we build a PKCS#8 key Java can understand
96
+ int pkcs1Length = pkcs1Bytes.length;
97
+ int totalLength = pkcs1Length + 22;
98
+ byte[] pkcs8Header = new byte[] {
99
+ 0x30,
100
+ (byte) 0x82,
101
+ (byte) ((totalLength >> 8) & 0xff),
102
+ (byte) (totalLength & 0xff), // Sequence + total length
103
+ 0x2,
104
+ 0x1,
105
+ 0x0, // Integer (0)
106
+ 0x30,
107
+ 0xD,
108
+ 0x6,
109
+ 0x9,
110
+ 0x2A,
111
+ (byte) 0x86,
112
+ 0x48,
113
+ (byte) 0x86,
114
+ (byte) 0xF7,
115
+ 0xD,
116
+ 0x1,
117
+ 0x1,
118
+ 0x1,
119
+ 0x5,
120
+ 0x0, // Sequence: 1.2.840.113549.1.1.1, NULL
121
+ 0x4,
122
+ (byte) 0x82,
123
+ (byte) ((pkcs1Length >> 8) & 0xff),
124
+ (byte) (pkcs1Length & 0xff) // Octet string + length
125
+ };
126
+ byte[] pkcs8bytes = join(pkcs8Header, pkcs1Bytes);
127
+ return readPkcs8PrivateKey(pkcs8bytes);
85
128
  }
86
- }
87
-
88
- private static byte[] join(byte[] byteArray1, byte[] byteArray2) {
89
- byte[] bytes = new byte[byteArray1.length + byteArray2.length];
90
- System.arraycopy(byteArray1, 0, bytes, 0, byteArray1.length);
91
- System.arraycopy(
92
- byteArray2,
93
- 0,
94
- bytes,
95
- byteArray1.length,
96
- byteArray2.length
97
- );
98
- return bytes;
99
- }
100
-
101
- private static PrivateKey readPkcs1PrivateKey(byte[] pkcs1Bytes)
102
- throws GeneralSecurityException {
103
- // We can't use Java internal APIs to parse ASN.1 structures, so we build a PKCS#8 key Java can understand
104
- int pkcs1Length = pkcs1Bytes.length;
105
- int totalLength = pkcs1Length + 22;
106
- byte[] pkcs8Header = new byte[] {
107
- 0x30,
108
- (byte) 0x82,
109
- (byte) ((totalLength >> 8) & 0xff),
110
- (byte) (totalLength & 0xff), // Sequence + total length
111
- 0x2,
112
- 0x1,
113
- 0x0, // Integer (0)
114
- 0x30,
115
- 0xD,
116
- 0x6,
117
- 0x9,
118
- 0x2A,
119
- (byte) 0x86,
120
- 0x48,
121
- (byte) 0x86,
122
- (byte) 0xF7,
123
- 0xD,
124
- 0x1,
125
- 0x1,
126
- 0x1,
127
- 0x5,
128
- 0x0, // Sequence: 1.2.840.113549.1.1.1, NULL
129
- 0x4,
130
- (byte) 0x82,
131
- (byte) ((pkcs1Length >> 8) & 0xff),
132
- (byte) (pkcs1Length & 0xff), // Octet string + length
133
- };
134
- byte[] pkcs8bytes = join(pkcs8Header, pkcs1Bytes);
135
- return readPkcs8PrivateKey(pkcs8bytes);
136
- }
137
-
138
- public static PrivateKey stringToPrivateKey(String private_key)
139
- throws GeneralSecurityException {
140
- // Base64 decode the result
141
-
142
- String pkcs1Pem = private_key;
143
- pkcs1Pem = pkcs1Pem.replace("-----BEGIN RSA PRIVATE KEY-----", "");
144
- pkcs1Pem = pkcs1Pem.replace("-----END RSA PRIVATE KEY-----", "");
145
- pkcs1Pem = pkcs1Pem.replace("\\n", "");
146
- pkcs1Pem = pkcs1Pem.replace(" ", "");
147
-
148
- byte[] pkcs1EncodedBytes = Base64.decode(
149
- pkcs1Pem.getBytes(),
150
- Base64.DEFAULT
151
- );
152
- // extract the private key
153
- return readPkcs1PrivateKey(pkcs1EncodedBytes);
154
- }
155
-
156
- public static void decryptFile(
157
- final File file,
158
- final String privateKey,
159
- final String ivSessionKey,
160
- final String version
161
- ) throws IOException {
162
- // (str != null && !str.isEmpty())
163
- if (privateKey == null || privateKey.isEmpty()) {
164
- Log.i(CapacitorUpdater.TAG, "Cannot found privateKey");
165
- return;
166
- } else if (
167
- ivSessionKey == null ||
168
- ivSessionKey.isEmpty() ||
169
- ivSessionKey.split(":").length != 2
170
- ) {
171
- Log.i(CapacitorUpdater.TAG, "Cannot found sessionKey");
172
- return;
129
+
130
+ public static PrivateKey stringToPrivateKey(String private_key) throws GeneralSecurityException {
131
+ // Base64 decode the result
132
+
133
+ String pkcs1Pem = private_key;
134
+ pkcs1Pem = pkcs1Pem.replace("-----BEGIN RSA PRIVATE KEY-----", "");
135
+ pkcs1Pem = pkcs1Pem.replace("-----END RSA PRIVATE KEY-----", "");
136
+ pkcs1Pem = pkcs1Pem.replace("\\n", "");
137
+ pkcs1Pem = pkcs1Pem.replace(" ", "");
138
+
139
+ byte[] pkcs1EncodedBytes = Base64.decode(pkcs1Pem.getBytes(), Base64.DEFAULT);
140
+ // extract the private key
141
+ return readPkcs1PrivateKey(pkcs1EncodedBytes);
173
142
  }
174
- try {
175
- String ivB64 = ivSessionKey.split(":")[0];
176
- String sessionKeyB64 = ivSessionKey.split(":")[1];
177
- byte[] iv = Base64.decode(ivB64.getBytes(), Base64.DEFAULT);
178
- byte[] sessionKey = Base64.decode(
179
- sessionKeyB64.getBytes(),
180
- Base64.DEFAULT
181
- );
182
- PrivateKey pKey = CryptoCipher.stringToPrivateKey(privateKey);
183
- byte[] decryptedSessionKey = CryptoCipher.decryptRSA(sessionKey, pKey);
184
- SecretKey sKey = CryptoCipher.byteToSessionKey(decryptedSessionKey);
185
- byte[] content = new byte[(int) file.length()];
186
-
187
- try (
188
- final FileInputStream fis = new FileInputStream(file);
189
- final BufferedInputStream bis = new BufferedInputStream(fis);
190
- final DataInputStream dis = new DataInputStream(bis)
191
- ) {
192
- dis.readFully(content);
193
- dis.close();
194
- byte[] decrypted = CryptoCipher.decryptAES(content, sKey, iv);
195
- // write the decrypted string to the file
196
- try (
197
- final FileOutputStream fos = new FileOutputStream(
198
- file.getAbsolutePath()
199
- )
200
- ) {
201
- fos.write(decrypted);
143
+
144
+ public static void decryptFile(final File file, final String privateKey, final String ivSessionKey, final String version)
145
+ throws IOException {
146
+ // (str != null && !str.isEmpty())
147
+ if (privateKey == null || privateKey.isEmpty()) {
148
+ Log.i(CapacitorUpdater.TAG, "Cannot found privateKey");
149
+ return;
150
+ } else if (ivSessionKey == null || ivSessionKey.isEmpty() || ivSessionKey.split(":").length != 2) {
151
+ Log.i(CapacitorUpdater.TAG, "Cannot found sessionKey");
152
+ return;
153
+ }
154
+ try {
155
+ String ivB64 = ivSessionKey.split(":")[0];
156
+ String sessionKeyB64 = ivSessionKey.split(":")[1];
157
+ byte[] iv = Base64.decode(ivB64.getBytes(), Base64.DEFAULT);
158
+ byte[] sessionKey = Base64.decode(sessionKeyB64.getBytes(), Base64.DEFAULT);
159
+ PrivateKey pKey = CryptoCipher.stringToPrivateKey(privateKey);
160
+ byte[] decryptedSessionKey = CryptoCipher.decryptRSA(sessionKey, pKey);
161
+ SecretKey sKey = CryptoCipher.byteToSessionKey(decryptedSessionKey);
162
+ byte[] content = new byte[(int) file.length()];
163
+
164
+ try (
165
+ final FileInputStream fis = new FileInputStream(file);
166
+ final BufferedInputStream bis = new BufferedInputStream(fis);
167
+ final DataInputStream dis = new DataInputStream(bis)
168
+ ) {
169
+ dis.readFully(content);
170
+ dis.close();
171
+ byte[] decrypted = CryptoCipher.decryptAES(content, sKey, iv);
172
+ // write the decrypted string to the file
173
+ try (final FileOutputStream fos = new FileOutputStream(file.getAbsolutePath())) {
174
+ fos.write(decrypted);
175
+ }
176
+ }
177
+ } catch (GeneralSecurityException e) {
178
+ Log.i(CapacitorUpdater.TAG, "decryptFile fail");
179
+ e.printStackTrace();
180
+ throw new IOException("GeneralSecurityException");
202
181
  }
203
- }
204
- } catch (GeneralSecurityException e) {
205
- Log.i(CapacitorUpdater.TAG, "decryptFile fail");
206
- e.printStackTrace();
207
- throw new IOException("GeneralSecurityException");
208
182
  }
209
- }
210
-
211
- public static String calcChecksum(File file) {
212
- final int BUFFER_SIZE = 1024 * 1024 * 5; // 5 MB buffer size
213
- CRC32 crc = new CRC32();
214
-
215
- try (FileInputStream fis = new FileInputStream(file)) {
216
- byte[] buffer = new byte[BUFFER_SIZE];
217
- int length;
218
- while ((length = fis.read(buffer)) != -1) {
219
- crc.update(buffer, 0, length);
220
- }
221
- return String.format("%08x", crc.getValue());
222
- } catch (IOException e) {
223
- System.err.println(
224
- CapacitorUpdater.TAG +
225
- " Cannot calc checksum: " +
226
- file.getPath() +
227
- " " +
228
- e.getMessage()
229
- );
230
- return "";
183
+
184
+ public static String calcChecksum(File file) {
185
+ final int BUFFER_SIZE = 1024 * 1024 * 5; // 5 MB buffer size
186
+ CRC32 crc = new CRC32();
187
+
188
+ try (FileInputStream fis = new FileInputStream(file)) {
189
+ byte[] buffer = new byte[BUFFER_SIZE];
190
+ int length;
191
+ while ((length = fis.read(buffer)) != -1) {
192
+ crc.update(buffer, 0, length);
193
+ }
194
+ return String.format("%08x", crc.getValue());
195
+ } catch (IOException e) {
196
+ System.err.println(CapacitorUpdater.TAG + " Cannot calc checksum: " + file.getPath() + " " + e.getMessage());
197
+ return "";
198
+ }
231
199
  }
232
- }
233
-
234
- public static PublicKey stringToPublicKey(String publicKey) {
235
- byte[] encoded = Base64.decode(publicKey, Base64.DEFAULT);
236
-
237
- KeyFactory keyFactory = null;
238
- try {
239
- keyFactory = KeyFactory.getInstance("RSA");
240
- X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
241
- return keyFactory.generatePublic(keySpec);
242
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
243
- Log.i(
244
- "Capacitor-updater",
245
- "stringToPublicKey fail\nError:\n" + e.toString()
246
- );
247
- return null;
200
+
201
+ public static PublicKey stringToPublicKey(String publicKey) {
202
+ byte[] encoded = Base64.decode(publicKey, Base64.DEFAULT);
203
+
204
+ KeyFactory keyFactory = null;
205
+ try {
206
+ keyFactory = KeyFactory.getInstance("RSA");
207
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
208
+ return keyFactory.generatePublic(keySpec);
209
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
210
+ Log.i("Capacitor-updater", "stringToPublicKey fail\nError:\n" + e.toString());
211
+ return null;
212
+ }
248
213
  }
249
- }
250
214
  }