/**
* Copyright (c) 2015 unfoldingWord
* http://creativecommons.org/licenses/MIT/
* See LICENSE file for details.
* Contributors:
* PJ Fechner <pj@actsmedia.com>
*/
package signing;
import android.content.Context;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.List;
import model.DaoDBHelper;
import model.daoModels.Book;
import model.daoModels.SigningOrganization;
import model.daoModels.Verification;
/**
* Created by PJ Fechner on 3/13/15.
* Class to deal with the signing for UW
*/
public class UWSigning {
private static final String TAG = "UWSigning";
// private static final String signatureJsonKey = "sig";
// private static final String signingEntityUrl = "https://pki.unfoldingword.org/uW-vk.pem";
private static final String stockCert = "certs/uW_vk_2.pem";
private static final String stockCertPub = "certs/ca.pub";
public static void updateBookVerification(Context context, Book book, byte[] text, String sigData) throws IOException{
ArrayList<Verification> verifications = getVerifications(context, text, sigData);
if(verifications != null) {
updateBookVerifications(context, verifications, book);
}
}
private static ArrayList<Verification> getVerifications(Context context, byte[] text, String sigData){
try {
// String sigData = URLDownloadUtil.downloadString(book.getSignatureUrl());
ArrayList<Verification> verifications = new ArrayList<>();
if(sigData.contains("404")){
Verification errorModel = new Verification();
errorModel.setStatus(2);
verifications.add(errorModel);
}
else {
JSONArray sigArray = new JSONArray(sigData);
for (int i = 0; i < sigArray.length(); i++) {
JSONObject obj = sigArray.getJSONObject(i);
Verification model = new Verification();
model = (Verification) model.setupModelFromJson(obj);
if (model == null) {
Verification errorModel = new Verification();
errorModel.setStatus(2);
verifications.add(errorModel);
break;
}
SigningEntity signingEntity = getSigningEntity(context);
Status sigStatus = signingEntity.verifyContent(model.getSignature(), text);
if (sigStatus != Status.VERIFIED) {
Log.e(TAG, "Signature not verified: " + sigStatus.toString());
} else {
Log.i(TAG, "Signature status: " + sigStatus.toString());
}
model.setStatus(sigStatus.ordinal());
verifications.add(model);
}
}
return verifications;
}
catch (JSONException e) {
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
return null;
}
private static void updateBookVerifications(Context context, List<Verification> newModels, Book book){
long bookId = book.getId();
List<Verification> currentVerifications = Verification.getModelsForBookId(bookId, DaoDBHelper.getDaoSession(context));
for(Verification oldModel : currentVerifications){
oldModel.delete();
}
for(Verification newModel : newModels){
newModel.setBook(book);
newModel.setBookId(bookId);
newModel.insertModel(DaoDBHelper.getDaoSession(context));
}
}
private static SigningEntity getSigningEntity(Context context) throws IOException{
InputStream uwKeyFile = context.getAssets().open(stockCertPub);
PublicKey uwPublicKey = Crypto.loadPublicECDSAKey(uwKeyFile);
// byte[] keyData = URLDownloadUtil.downloadBytes(signingEntityUrl);
InputStream signingStream = context.getAssets().open(stockCert);
SigningEntity entity = SigningEntity.generateFromIdentity(uwPublicKey, signingStream);
if(entity != null) {
updateOrganization(context, entity.organization);
}
return entity;
}
synchronized private static void updateOrganization(Context context, Organization org){
SigningOrganization oldOrg = SigningOrganization.getModelForUniqueSlug(org.slug, DaoDBHelper.getDaoSession(context));
if(oldOrg == null){
SigningOrganization signingOrg = new SigningOrganization();
signingOrg.updateWithOrganization(org, DaoDBHelper.getDaoSession(context));
}
else{
oldOrg.updateWithOrganization(org, DaoDBHelper.getDaoSession(context));
}
}
}