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.ASN1;
47 import com.android.se.security.arf.DERParser;
48 import com.android.se.security.arf.SecureElement;
49 import com.android.se.security.arf.SecureElementException;
50 import com.android.se.security.gpac.AID_REF_DO;
51 
52 import java.io.IOException;
53 import java.util.HashMap;
54 import java.util.Map;
55 
56 /** EF_ACRules related features */
57 public class EFACRules extends EF {
58 
59     public static final String TAG = "ACE ARF EF_ACRules";
60     // AID used to store rules for default application
61     public static final byte[] DEFAULT_APP = new byte[0];
62 
63     protected Map<String, byte[]> mAcConditionDataCache = new HashMap<String, byte[]>();
64 
65     /**
66      * Constructor
67      *
68      * @param secureElement SE on which ISO7816 commands are applied
69      */
EFACRules(SecureElement handle)70     public EFACRules(SecureElement handle) {
71         super(handle);
72     }
73 
74     /**
75      * Decodes EF_ACRules file
76      *
77      * @param buffer ASN.1 data
78      */
decodeDER(byte[] buffer)79     private void decodeDER(byte[] buffer) throws IOException, PKCS15Exception {
80         byte[] aid = null;
81         DERParser der = new DERParser(buffer);
82 
83         // mapping to GPAC data objects
84         int tag = 0;
85 
86         while (!der.isEndofBuffer()) {
87             der.parseTLV(ASN1.TAG_Sequence);
88             switch (der.parseTLV()) {
89                 case (byte) 0xA0: // Restricted AID
90                     der.parseTLV(ASN1.TAG_OctetString);
91                     aid = der.getTLVData();
92                     tag = AID_REF_DO.TAG;
93                     break;
94                 case (byte) 0x81: // Rules for default Application
95                     aid = null;
96                     tag = AID_REF_DO.TAG_DEFAULT_APPLICATION;
97                     break;
98                 case (byte) 0x82: // Rules for default case
99                     aid = DEFAULT_APP;
100                     tag = AID_REF_DO.TAG;
101                     break;
102                 default:
103                     throw new PKCS15Exception("[Parser] Unexpected ACRules entry");
104             }
105             byte[] path = der.parsePathAttributes();
106 
107             // 2012-09-04
108             // optimization of reading EF ACCondition
109             if (path != null) {
110                 String pathString = ByteArrayConverter.byteArrayToHexString(path);
111                 EFACConditions temp = new EFACConditions(mSEHandle, new AID_REF_DO(tag, aid));
112                 // check if EF was already read before
113                 if (this.mAcConditionDataCache.containsKey(pathString)) {
114                     // yes, then reuse data
115                     temp.addRestrictedHashesFromData(this.mAcConditionDataCache.get(pathString));
116                 } else {
117                     // no, read EF and add to rules cache
118                     temp.addRestrictedHashes(path);
119                     if (temp.getData() != null) {
120                         // if data are read the put it into cache.
121                         this.mAcConditionDataCache.put(pathString, temp.getData());
122                     }
123                 }
124             }
125         }
126     }
127 
128     /**
129      * Selects and Analyses EF_ACRules file
130      *
131      * @param path Path of the "EF_ACRules" file
132      */
analyseFile(byte[] path)133     public void analyseFile(byte[] path) throws IOException, PKCS15Exception,
134             SecureElementException {
135         Log.i(TAG, "Analysing EF_ACRules...");
136 
137         // clear EF AC Condition data cache.
138         mAcConditionDataCache.clear();
139 
140         if (selectFile(path) != APDU_SUCCESS) throw new PKCS15Exception("EF_ACRules not found!!");
141 
142         try {
143             decodeDER(readBinary(0, Util.END));
144         } catch (PKCS15Exception e) {
145             throw e;
146         }
147     }
148 }
149