1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 /* 17 * Copyright (c) 2015-2017, The Linux Foundation. 18 */ 19 20 /* 21 * Copyright (C) 2011 Deutsche Telekom, A.G. 22 * 23 * Licensed under the Apache License, Version 2.0 (the "License"); 24 * you may not use this file except in compliance with the License. 25 * You may obtain a copy of the License at 26 * 27 * http://www.apache.org/licenses/LICENSE-2.0 28 * 29 * Unless required by applicable law or agreed to in writing, software 30 * distributed under the License is distributed on an "AS IS" BASIS, 31 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 32 * See the License for the specific language governing permissions and 33 * limitations under the License. 34 */ 35 36 /* 37 * Contributed by: Giesecke & Devrient GmbH. 38 */ 39 40 package com.android.se.security.arf.pkcs15; 41 42 import android.util.Log; 43 44 import com.android.se.internal.ByteArrayConverter; 45 import com.android.se.internal.Util; 46 import com.android.se.security.arf.DERParser; 47 import com.android.se.security.arf.SecureElement; 48 import com.android.se.security.arf.SecureElementException; 49 50 import java.io.IOException; 51 52 /** EF_ODF related features */ 53 public class EFODF extends EF { 54 55 // Standardized ID for EF_ODF file 56 public static final byte[] EFODF_PATH = {0x50, 0x31}; 57 public final String mTag = "SecureElement-ARF-EFODF"; 58 byte[] mCDFPath = null; 59 60 /** 61 * Constructor 62 * 63 * @param secureElement SE on which ISO7816 commands are applied 64 */ EFODF(SecureElement handle)65 public EFODF(SecureElement handle) { 66 super(handle); 67 } 68 69 /** 70 * Decodes EF_ODF file 71 * 72 * @param buffer ASN.1 data 73 * @return Path to "EF_DODF" from "DODF Tag" entry; <code>null</code> otherwise 74 */ decodeDER(byte[] buffer)75 private byte[] decodeDER(byte[] buffer) throws PKCS15Exception { 76 DERParser der = new DERParser(buffer); 77 while (!der.isEndofBuffer()) { 78 if (der.parseTLV() == (byte) 0xA5) { // CDF 79 mCDFPath = der.parsePathAttributes(); 80 Log.i( 81 mTag, 82 "ODF content found mCDFPath :" + ByteArrayConverter.byteArrayToHexString( 83 mCDFPath)); 84 } else { 85 der.skipTLVData(); 86 } 87 } 88 89 DERParser der2 = new DERParser(buffer); 90 while (!der2.isEndofBuffer()) { 91 if (der2.parseTLV() == (byte) 0xA7) { // DODF 92 return der2.parsePathAttributes(); 93 } else { 94 der2.skipTLVData(); 95 } 96 } 97 return null; 98 } 99 getCDFPath()100 public byte[] getCDFPath() { 101 return mCDFPath; 102 } 103 104 /** 105 * Selects and Analyses EF_ODF file 106 * 107 * @return Path to "EF_DODF" from "DODF Tag" entry; <code>null</code> otherwise 108 */ analyseFile(byte[] pkcs15Path)109 public byte[] analyseFile(byte[] pkcs15Path) throws IOException, PKCS15Exception, 110 SecureElementException { 111 Log.i(mTag, "Analysing EF_ODF..."); 112 113 // 2012-04-12 114 // extend path if ODF path was determined from EF DIR. 115 byte[] path = null; 116 if (pkcs15Path != null) { 117 path = new byte[pkcs15Path.length + EFODF_PATH.length]; 118 System.arraycopy(pkcs15Path, 0, path, 0, pkcs15Path.length); 119 System.arraycopy(EFODF_PATH, 0, path, pkcs15Path.length, EFODF_PATH.length); 120 } else { 121 path = EFODF_PATH; 122 } 123 // --- 124 125 if (selectFile(path) != APDU_SUCCESS) { 126 // let's give it another try.. 127 try { 128 synchronized (this) { 129 wait(1000); 130 } 131 } catch (InterruptedException e) { 132 Log.e(mTag, "Interupted while waiting for EF_ODF : " + e); 133 } 134 if (selectFile(path) != APDU_SUCCESS) throw new PKCS15Exception("EF_ODF not found!!"); 135 } 136 return decodeDER(readBinary(0, Util.END)); 137 } 138 } 139