-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
194 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,49 @@ | ||
Cordova Plugin Template | ||
====== | ||
# cordova-plugin-androidapkinfo | ||
A cordova plugin to retrieve android package signatures info | ||
|
||
This is a simple starting point for building a Cordova plugin on iOS and Android. | ||
## Installation | ||
``` | ||
cordova plugin add cordova-plugin-androidapkinfo | ||
``` | ||
|
||
## How to use | ||
|
||
``` | ||
//once device is ready | ||
AndroidAPKInfoPlugin.signatures(function(result) { | ||
console.debug("result", result); | ||
}) | ||
AndroidAPKInfoPlugin.APKSignatures("file:///path/to/package.apk", function(result) { | ||
console.debug("result", result); | ||
}) | ||
AndroidAPKInfoPlugin.packageSignatures("com.company.packagename", function(result) { | ||
console.debug("result", result); | ||
}) | ||
``` | ||
|
||
### Description of the result object | ||
```json | ||
{ | ||
"signatures": [ | ||
{ | ||
"charString": "aeawqwq....", | ||
"hashcode": 342234324234, | ||
"info": { | ||
"issuer_dn": "CN=Android Debug, O=Android, C=US", | ||
"serialnumber": 13242134123, | ||
"subject_dn": "CN=Android Debug, O=Android, C=US" | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
## Contributing | ||
|
||
1. Fork it | ||
2. Create your feature branch (`git checkout -b my-new-feature`) | ||
3. Commit your changes (`git commit -am 'Add some feature'`) | ||
4. Push to the branch (`git push origin my-new-feature`) | ||
5. Create new Pull Request |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,149 @@ | ||
/** | ||
*/ | ||
package com.example; | ||
package net.siteed; | ||
|
||
import android.content.Context; | ||
import android.content.pm.PackageManager; | ||
import android.content.pm.Signature; | ||
import android.util.Log; | ||
|
||
import org.apache.cordova.CallbackContext; | ||
import org.apache.cordova.CordovaInterface; | ||
import org.apache.cordova.CordovaPlugin; | ||
import org.apache.cordova.CordovaWebView; | ||
import org.apache.cordova.PluginResult; | ||
import org.apache.cordova.PluginResult.Status; | ||
import org.json.JSONObject; | ||
import org.json.JSONArray; | ||
import org.json.JSONException; | ||
import org.json.JSONObject; | ||
|
||
import android.util.Log; | ||
import java.io.ByteArrayInputStream; | ||
import java.io.File; | ||
import java.io.InputStream; | ||
import java.security.cert.CertificateException; | ||
import java.security.cert.CertificateFactory; | ||
import java.security.cert.X509Certificate; | ||
|
||
public class AndroidAPKInfoPlugin extends CordovaPlugin { | ||
private static final String TAG = "AndroidAPKInfoPlugin"; | ||
|
||
public void initialize(CordovaInterface cordova, CordovaWebView webView) { | ||
super.initialize(cordova, webView); | ||
|
||
Log.d(TAG, "Initializing AndroidAPKInfoPlugin"); | ||
} | ||
|
||
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException { | ||
|
||
if (action.equals("signatures")) { | ||
Context context = cordova.getActivity().getApplicationContext(); | ||
String packageName = context.getPackageName(); | ||
this.getPackageSignatures(packageName, callbackContext); | ||
} else if (action.equals("APKSignatures")) { | ||
String apkPath = args.getString(0); | ||
this.getAPKSignatures(apkPath, callbackContext); | ||
} else if (action.equals("packageSignatures")) { | ||
String packageName = args.getString(0); | ||
this.getPackageSignatures(packageName, callbackContext); | ||
} else { | ||
JSONObject errorObj = new JSONObject(); | ||
errorObj.put("status", PluginResult.Status.INVALID_ACTION.ordinal()); | ||
errorObj.put("message", "Invalid action"); | ||
callbackContext.error(errorObj); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
import java.util.Date; | ||
/** | ||
* Get the list of signatures for the APK given in parameters | ||
* | ||
* @param apkFile | ||
* @param callbackContext | ||
* @throws JSONException | ||
*/ | ||
private void getAPKSignatures(String apkFile, final CallbackContext callbackContext) throws JSONException { | ||
JSONObject resultObj = new JSONObject(); | ||
|
||
public class MyCordovaPlugin extends CordovaPlugin { | ||
private static final String TAG = "MyCordovaPlugin"; | ||
Log.d(TAG, "getAPKSignatures for "+apkFile); | ||
|
||
public void initialize(CordovaInterface cordova, CordovaWebView webView) { | ||
super.initialize(cordova, webView); | ||
File file = new File(apkFile); | ||
if (file.exists()) { | ||
PackageManager pm = cordova.getActivity().getPackageManager(); | ||
Context context = cordova.getActivity().getApplicationContext(); | ||
|
||
Log.d(TAG, "Initializing MyCordovaPlugin"); | ||
} | ||
Signature[] sigs = pm.getPackageArchiveInfo(apkFile, PackageManager.GET_SIGNATURES).signatures; | ||
resultObj.put("signatures", getJSONFromSignatures(sigs)); | ||
|
||
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException { | ||
if(action.equals("echo")) { | ||
String phrase = args.getString(0); | ||
// Echo back the first argument | ||
Log.d(TAG, phrase); | ||
} else if(action.equals("getDate")) { | ||
// An example of returning data back to the web layer | ||
final PluginResult result = new PluginResult(PluginResult.Status.OK, (new Date()).toString()); | ||
callbackContext.sendPluginResult(result); | ||
} else { | ||
JSONObject errorObj = new JSONObject(); | ||
errorObj.put("status", PluginResult.Status.ERROR.ordinal()); | ||
errorObj.put("message", "File not found"); | ||
callbackContext.error(errorObj); | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Get the list of signatures for the given package name. | ||
* | ||
* @param packageName | ||
* @param callbackContext | ||
* @throws JSONException | ||
*/ | ||
private void getPackageSignatures(String packageName, final CallbackContext callbackContext) throws JSONException { | ||
JSONObject resultObj = new JSONObject(); | ||
|
||
Log.d(TAG, "getPackageSignatures for "+packageName); | ||
|
||
PackageManager pm = cordova.getActivity().getPackageManager(); | ||
|
||
try { | ||
Signature[] sigs = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures; | ||
resultObj.put("signatures", getJSONFromSignatures(sigs)); | ||
|
||
callbackContext.success(resultObj); | ||
} catch (PackageManager.NameNotFoundException e) { | ||
e.printStackTrace(); | ||
callbackContext.error(resultObj); | ||
} | ||
} | ||
|
||
private JSONArray getJSONFromSignatures(Signature[] sigs) throws JSONException { | ||
JSONArray jsonSigs = new JSONArray(); | ||
for (Signature sig : sigs) { | ||
Log.i(TAG, "Signature hashcode : " + sig.hashCode()); | ||
JSONObject jsonSig = new JSONObject(); | ||
jsonSig.put("hashcode", sig.hashCode()); | ||
jsonSig.put("charsString", sig.toCharsString()); | ||
jsonSig.put("info", getSignatureInfo(sig)); | ||
jsonSigs.put(jsonSig); | ||
} | ||
return jsonSigs; | ||
} | ||
|
||
/** | ||
* Get x509 cert info about a signature | ||
* | ||
* @param sig | ||
* @return JSONObject | ||
* @throws JSONException | ||
*/ | ||
private JSONObject getSignatureInfo(Signature sig) throws JSONException { | ||
JSONObject resultObj = new JSONObject(); | ||
try { | ||
final byte[] rawCert = sig.toByteArray(); | ||
InputStream certStream = new ByteArrayInputStream(rawCert); | ||
|
||
CertificateFactory certFactory = CertificateFactory.getInstance("X509"); | ||
X509Certificate x509Cert = (X509Certificate) certFactory.generateCertificate(certStream); | ||
|
||
|
||
resultObj.put("subject_dn", x509Cert.getSubjectDN()); | ||
resultObj.put("issuer_dn", x509Cert.getIssuerDN()); | ||
resultObj.put("serialnumber", x509Cert.getSerialNumber()); | ||
|
||
} catch (CertificateException e) { | ||
resultObj.put("error", "invalid certificate"); | ||
} | ||
return resultObj; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,18 @@ | ||
|
||
var exec = require('cordova/exec'); | ||
|
||
var PLUGIN_NAME = 'AndroidAPKInfo'; | ||
var PLUGIN_NAME = 'AndroidAPKInfoPlugin'; | ||
|
||
var AndroidAPKInfo = { | ||
echo: function(phrase, cb) { | ||
exec(cb, null, PLUGIN_NAME, 'echo', [phrase]); | ||
var AndroidAPKInfoPlugin = { | ||
signatures: function(cb) { | ||
exec(cb, null, PLUGIN_NAME, 'signatures', []); | ||
}, | ||
getDate: function(cb) { | ||
exec(cb, null, PLUGIN_NAME, 'getDate', []); | ||
APKSignatures: function(params, cb) { | ||
exec(cb, null, PLUGIN_NAME, 'APKSignatures', [params]); | ||
}, | ||
packageSignatures: function(params, cb) { | ||
exec(cb, null, PLUGIN_NAME, 'packageSignatures', [params]); | ||
} | ||
}; | ||
|
||
module.exports = AndroidAPKInfo; | ||
module.exports = AndroidAPKInfoPlugin; |