/**
* Copyright 2014 Daum Kakao Corp.
*
* Redistribution and modification in source or binary forms are not permitted without specific prior written permission.
*
* 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 com.kakao.helper;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
/**
* Talk을 비롯하여 카카오 서비스와 통신하기 위한 protocol
* authorization을 각 서비스를 통해 하는 경우
* [Notice] talk이 젤 먼저 적용되면서 key이름에 모두 talk이 붙어 있는데 실제로는 모든 카카오 서비스가 같은 프로토콜을 사용한다.
*
* @author MJ
*/
public class KakaoServiceProtocol {
public static final int MESSAGE_GET_AUTH_CODE_REQUEST = 0x10000;
public static final int MESSAGE_GET_AUTH_CODE_REPLY = 0x10001;
//===[Notice] talk이 젤 먼저 적용되면서 key이름에 모두 talk이 붙어 있는데 실제로는 모든 카카오 서비스가 같은 프로토콜을 사용한다.
//request
protected static final String EXTRA_PROTOCOL_VERSION = "com.kakao.sdk.talk.protocol.version";
protected static final int PROTOCOL_VERSION = 1;
protected static final String EXTRA_APPLICATION_KEY = "com.kakao.sdk.talk.appKey";
protected static final String EXTRA_REDIRECT_URI = "com.kakao.sdk.talk.redirectUri";
//response
public static final String EXTRA_REDIRECT_URL = "com.kakao.sdk.talk.redirectUrl";
public static final String EXTRA_ERROR_DESCRIPTION = "com.kakao.sdk.talk.error.description";
public static final String EXTRA_ERROR_TYPE = "com.kakao.sdk.talk.error.type";
//===[Notice]
// error types
public static final String NOT_SUPPORT_ERROR = "NotSupportError";
public static final String ERROR_UNKNOWN_ERROR = "UnknownError";
public static final String ERROR_PROTOCOL_ERROR = "ProtocolError";
public static final String ERROR_APPLICATION_ERROR = "ApplicationError";
public static final String ERROR_NETWORK_ERROR = "NetworkError";
private static final String RELEASE_SIGNATURE = "308201db30820144a00302010202044c707197300d06092a864886f70d010105050030" +
"31310b3009060355040613026b6f310e300c060355040a13056b616b616f31123010060355040b13096b616b616f7465616d3020170d" +
"3130303832323030333834375a180f32313130303732393030333834375a3031310b3009060355040613026b6f310e300c060355040a" +
"13056b616b616f31123010060355040b13096b616b616f7465616d30819f300d06092a864886f70d010101050003818d003081890281" +
"8100aef387bc86e022a87e66b8c42153284f18e0c468cf9c87a241b989729dfdad3dd9e1847546d01a2819ba77f3974a47b473c926ac" +
"ae173fd90c7e635000721feeef6705da7ae949a35b82900a0f67d9464d73ed8a98c37f4ac70729494a17469bc40d4ee06d043b09147e" +
"badc55fa1020968d7036c5fb9b8c148cba1d8e9d9fc10203010001300d06092a864886f70d0101050500038181005569be704c68cff6" +
"221c1e04dd8a131110f9f5cd2138042286337fd6014a1b1d2d3eeb266ae1630afe56bf63c07dd0b5c8fad46dcb9f802f9a7802fb89eb" +
"3b4777b9665bb1ed9feaf1dc7cac4f91abedfc81187ff6d2f471dbd12335d2c0ef0e2ee719df6e763f814b9ac91f8be37fd11d406867" +
"00d66be6de22a1836f060f01";
private static final String DEBUG_SIGNATURE = "308201e53082014ea00302010202044f4ae542300d06092a864886f70d01010505003037" +
"310b30090603550406130255533110300e060355040a1307416e64726f6964311630140603550403130d416e64726f69642044656275" +
"67301e170d3132303232373032303635385a170d3432303231393032303635385a3037310b30090603550406130255533110300e0603" +
"55040a1307416e64726f6964311630140603550403130d416e64726f696420446562756730819f300d06092a864886f70d0101010500" +
"03818d0030818902818100c0b41c25ef21a39a13ce89c82dc3a14bf9ef0c3094aa2ac1bf755c9699535e79119e8b980c0ecdcc51f259" +
"eb0d8b2077d41de8fcfdeaac3f386c05e2a684ecb5504b660ad7d5a01cce35899f96bcbd099c9dcb274c6eb41fef861616a12fb45bc5" +
"7a19683a8a97ab1a33d9c70128878b67dd1b3a388ad5121d1d66ff04c065ff0203010001300d06092a864886f70d0101050500038181" +
"000418a7dacb6d13eb61c8270fe1fdd006eb66d0ff9f58f475defd8dc1fb11c41e34ce924531d1fd8ad26d9479d64f54851bf57b8dfe" +
"3a5d6f0a01dcad5b8c36ac4ac48caeff37888c36483c26b09aaa9689dbb896938d5afe40135bf7d9f12643046301867165d28be0baa3" +
"513a5084e182f7f9c044d5baa58bdce55fa1845241";
protected static Intent checkSupportedService(final Context context, final Intent intent, final int minVersion) {
if (intent == null) {
return null;
}
// 해당 intent를 지원하는 kakaotalk인지 check
ResolveInfo resolveInfo = Utility.resolveIntent(context, intent);
if (resolveInfo == null) {
return null;
}
// 설치된 kakaotalk이 변조된 것인지 check
if (!validateTalkSignatureAndMinVersion(context, resolveInfo.activityInfo.packageName, minVersion)) {
return null;
}
return intent;
}
private static boolean validateTalkSignatureAndMinVersion(final Context context, final String packageName, final int minVersion) {
PackageInfo talkPackageInfo;
try {
talkPackageInfo = context.getPackageManager().getPackageInfo(packageName,
PackageManager.GET_SIGNATURES);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
if(minVersion > 0){
if(talkPackageInfo.versionCode < minVersion)
return false;
}
for (Signature signature : talkPackageInfo.signatures) {
String signatureCharsString = signature.toCharsString();
if (signatureCharsString.equals(RELEASE_SIGNATURE) ||
signatureCharsString.equals(DEBUG_SIGNATURE)) {
return true;
}
}
return false;
}
public static boolean isCapriProtocolMatched(final Intent data) {
int protocolVersion = data.getIntExtra(EXTRA_PROTOCOL_VERSION, 0);
return ((PROTOCOL_VERSION == protocolVersion));
}
}