/* * Copyright 2012 The Stanford MobiSocial Laboratory * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mobisocial.corral; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import mobisocial.crypto.IBHashedIdentity; import mobisocial.crypto.IBHashedIdentity.Authority; import mobisocial.crypto.IBIdentity; import mobisocial.crypto.IBSignatureScheme.UserKey; import mobisocial.musubi.App; import mobisocial.musubi.encoding.NeedsKey.Signature; import mobisocial.musubi.identity.AphidIdentityProvider; import mobisocial.musubi.identity.IdentityProvider; import mobisocial.musubi.model.MIdentity; import mobisocial.musubi.model.helpers.IdentitiesManager; import mobisocial.musubi.model.helpers.UserKeyManager; import mobisocial.musubi.provider.TestSettingsProvider.Settings; import mobisocial.musubi.util.CertifiedHttpClient; import mobisocial.musubi.util.Util; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class CorralTicketProvider { private String TAG = "CorralTicketProvider"; private Context mContext; private static final String SERVER_URL = null; private static final int TYPE_OTHER = 0; private static final int TYPE_EMAIL = 1; private static final int TYPE_PHONE = 2; private static final int TYPE_OPENID = 3; private static final int TYPE_TWITTER = 4; private static final int TYPE_FACEBOOK = 5; private IdentitiesManager mIdentitiesManager; private SQLiteOpenHelper mDatabaseSource; private UserKeyManager mUserKeyManager; private IdentityProvider mIdentityProvider; private CookieStore cookieStore = null; private String myidentity=null; private String mysign=null; private String datestr=null; public CorralTicketProvider(Context context){ mContext = context; cookieStore = null; // from AphidIdentityProvider.java mDatabaseSource = App.getDatabaseSource(mContext); mIdentitiesManager = new IdentitiesManager(mDatabaseSource); // from MusubiService.java Settings test_settings = App.getTestSettings(mContext); if(test_settings != null && test_settings.mAlternateIdentityProvider != null) { mIdentityProvider = test_settings.mAlternateIdentityProvider; } else { mIdentityProvider = new AphidIdentityProvider(mContext); } // from KeyUpdateHandler.java mUserKeyManager = new UserKeyManager(mIdentityProvider.getEncryptionScheme(), mIdentityProvider.getSignatureScheme(), mDatabaseSource); } public String getObjName(byte[] key){ return CorralHelper.bin2hex(Util.sha256(key)); } public String getDatestr(){ return datestr; } public String getUploadTicket(String objName, String type, String length, String md5) throws IOException, JSONException{ if (SERVER_URL == null) { Log.w(TAG, "no file upload service"); return null; } String ticket = null; // get Identity setIdentityAndSignature(null); if(myidentity==null){ Log.e(TAG, "Failed to get IDENTITY."); return null; } String shortidentity = myidentity.substring(0,66); String url = SERVER_URL+"user/"+shortidentity+"/object/"+objName+"/upload-ticket/"+type+"/"+length+"/"+md5; Log.d(TAG, "Now accessing: "+url); // Set up HTTP request DefaultHttpClient http = new CertifiedHttpClient(mContext); http.setCookieStore(cookieStore); HttpGet httpget = new HttpGet(url); // httpget.setHeader( "Connection", "Keep-Alive" ); HttpResponse response = http.execute(httpget); Log.d(TAG, "StatusCode: "+response.getStatusLine().getStatusCode()); // TODO DELETE Header[] headers = response.getAllHeaders(); for(Header header: headers){ Log.d(TAG, "Header: name=" + header.getName() + ", val=" + header.getValue()); } if(response.getStatusLine().getStatusCode()==HttpStatus.SC_FORBIDDEN){ Header header = response.getFirstHeader("WWW-Authenticate"); if(header==null){ Log.e(TAG, "Failed to get Corral header."); return null; } String headervalue = header.getValue(); if(!headervalue.startsWith("Corral=")){ Log.e(TAG, "Failed to get Corral header."); return null; } String[] str = headervalue.split("\""); String challenge = str[1]; setIdentityAndSignature(challenge); if(mysign==null || myidentity==null){ Log.e(TAG, "Failed to get IDENTITY and SIGNATURE."); return null; } httpget.setHeader("Authorization", "Corral "+myidentity+" "+mysign); Log.d(TAG, "Corral "+myidentity+" "+mysign); response = http.execute(httpget); Log.d(TAG, "StatusCode: "+response.getStatusLine().getStatusCode()); } if(response.getStatusLine().getStatusCode()==200){ cookieStore = http.getCookieStore(); Log.d(TAG, "Saved Cookie: "+cookieStore.getCookies().get(0).getValue()); BufferedReader rd = new BufferedReader(new InputStreamReader( response.getEntity().getContent())); String responseStr = ""; String line = ""; while ((line = rd.readLine()) != null) { responseStr += line; } Log.d(TAG, "Server response:" + responseStr); JSONObject jso = new JSONObject(responseStr); ticket = jso.getString("ticket"); datestr = jso.getString("date"); } return ticket; } public void putACL(String objName, MIdentity[] buddies) throws ClientProtocolException, IOException { if (SERVER_URL == null) { Log.w(TAG, "no file upload service"); return; } Log.d(TAG, "---Start to Put ACL---"); int i = 0; String[] ident = new String[buddies.length]; for(MIdentity buddy: buddies){ ident[i] = getShortIdentity(buddy); i++; } String shortidentity = getShortIdentity(mIdentitiesManager.getMyDefaultIdentity()); String url = SERVER_URL+"user/"+shortidentity+"/object/"+objName+"/update-acl/"; // Set up HTTP request DefaultHttpClient http = new CertifiedHttpClient(mContext); http.setCookieStore(cookieStore); HttpPost httppost = new HttpPost(url); String postdata = ""; for(MIdentity buddy: buddies){ String si = getShortIdentity(buddy); if(si!=null){ if(postdata.length()>0){ postdata+=","; } postdata+=si; } } List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(1); nameValuePair.add(new BasicNameValuePair("identities", postdata)); httppost.setEntity(new UrlEncodedFormEntity(nameValuePair)); HttpResponse response = http.execute(httppost); if(response.getStatusLine().getStatusCode()!=HttpStatus.SC_OK){ throw new IOException("Failed to post ACL. StatusCode:"+response.getStatusLine().getStatusCode()); } } public String getDownloadTicket(String objName) throws IOException, JSONException{ if (SERVER_URL == null) { Log.w(TAG, "no file upload service"); return null; } String ticket = null; // get Identity setIdentityAndSignature(null); if(myidentity==null){ Log.e(TAG, "Failed to get IDENTITY."); return null; } String shortidentity = myidentity.substring(0,66); String url = SERVER_URL+"user/"+shortidentity+"/object/"+objName+"/download-ticket/"; Log.d(TAG, "Now accessing: "+url); // Set up HTTP request DefaultHttpClient http = new CertifiedHttpClient(mContext); http.setCookieStore(cookieStore); HttpGet httpget = new HttpGet(url); // httpget.setHeader( "Connection", "Keep-Alive" ); HttpResponse response = http.execute(httpget); Log.d(TAG, "StatusCode: "+response.getStatusLine().getStatusCode()); // TODO DELETE Header[] headers = response.getAllHeaders(); for(Header header: headers){ Log.d(TAG, "Header: name=" + header.getName() + ", val=" + header.getValue()); } if(response.getStatusLine().getStatusCode()==HttpStatus.SC_FORBIDDEN){ Header header = response.getFirstHeader("WWW-Authenticate"); if(header==null){ Log.e(TAG, "Failed to get Corral header."); return null; } String headervalue = header.getValue(); if(!headervalue.startsWith("Corral=")){ Log.e(TAG, "Failed to get Corral header."); return null; } String[] str = headervalue.split("\""); String challenge = str[1]; setIdentityAndSignature(challenge); if(mysign==null || myidentity==null){ Log.e(TAG, "Failed to get IDENTITY and SIGNATURE."); return null; } httpget.setHeader("Authorization", "Corral "+myidentity+" "+mysign); Log.d(TAG, "Corral "+myidentity+" "+mysign); response = http.execute(httpget); Log.d(TAG, "StatusCode: "+response.getStatusLine().getStatusCode()); } if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){ cookieStore = http.getCookieStore(); Log.d(TAG, "Saved Cookie: "+cookieStore.getCookies().get(0).getValue()); BufferedReader rd = new BufferedReader(new InputStreamReader( response.getEntity().getContent())); String responseStr = ""; String line = ""; while ((line = rd.readLine()) != null) { responseStr += line; } JSONObject jso = new JSONObject(responseStr); ticket = jso.getString("ticket"); datestr = jso.getString("date"); } return ticket; } private void setIdentityAndSignature(String challenge){ MIdentity id = mIdentitiesManager.getMyDefaultIdentity(); IBIdentity ident = IdentitiesManager.toIBIdentity(id, IdentitiesManager.computeTemporalFrameFromHash(id.principalHash_)); try { UserKey userkey = mUserKeyManager.getSignatureKey(id, ident); int type = getTypeByAuthority(ident.authority_); myidentity = String.format("%02x", type)+ CorralHelper.bin2hex(id.principalHash_)+ String.format("%016x", ident.temporalFrame_); if(challenge!=null){ // String signature = CorralHelper.bin2hex(userkey.key_); IBHashedIdentity from = new IBHashedIdentity(ident.authority_, ident.hashed_, ident.temporalFrame_); byte[] signed = mIdentityProvider.getSignatureScheme().sign(from, userkey, challenge.getBytes()); mysign = CorralHelper.bin2hex(signed); } } catch (Signature e) { Log.e(TAG, "Key needs to be updated..."); // TODO Withdraw Signature key from server like this... // UserKey n_userkey = mIdentityProvider.syncGetSignatureKey(from); e.printStackTrace(); return; } } private String getShortIdentity(MIdentity id){ int type = getTypeByAuthority(id.type_); return String.format("%02x", type)+CorralHelper.bin2hex(id.principalHash_); } private int getTypeByAuthority(Authority ath){ int type=TYPE_OTHER; switch(ath){ case Email: type = TYPE_EMAIL; break; case PhoneNumber: type = TYPE_PHONE; break; case OpenID: type = TYPE_OPENID; break; case Twitter: type = TYPE_TWITTER; break; case Facebook: type = TYPE_FACEBOOK; break; } return type; } }