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 package com.android.se.security.arf.pkcs15;
37 
38 import android.util.Log;
39 
40 import com.android.se.internal.Util;
41 import com.android.se.security.arf.ASN1;
42 import com.android.se.security.arf.DERParser;
43 import com.android.se.security.arf.SecureElement;
44 import com.android.se.security.arf.SecureElementException;
45 
46 import java.io.IOException;
47 
48 /** EF_DODF related features */
49 public class EFDODF extends EF {
50 
51     public static final String TAG = "ACE ARF EF_DODF";
52     // OID defined by Global Platform for the "Access Control"
53     public static final String AC_OID = "1.2.840.114283.200.1.1";
54 
55     /**
56      * Constructor
57      *
58      * @param secureElement SE on which ISO7816 commands are applied
59      */
EFDODF(SecureElement handle)60     public EFDODF(SecureElement handle) {
61         super(handle);
62     }
63 
64     /**
65      * Decodes EF_DODF file
66      *
67      * @param buffer ASN.1 data
68      * @return Path to "Access Control Main" from "Access Control" OID; <code>null</code> otherwise
69      */
decodeDER(byte[] buffer)70     private byte[] decodeDER(byte[] buffer) throws PKCS15Exception {
71         byte objectType;
72         short[] context = null;
73         DERParser der = new DERParser(buffer);
74 
75         while (!der.isEndofBuffer()) {
76             if (der.parseTLV() == (byte) 0xA1) { // OidDO Data Object
77                 // Common Object Attributes
78                 der.parseTLV(ASN1.TAG_Sequence);
79                 der.skipTLVData();
80                 // Common Data Object Attributes
81                 der.parseTLV(ASN1.TAG_Sequence);
82                 der.skipTLVData();
83 
84                 objectType = der.parseTLV();
85                 if (objectType == (byte) 0xA0) { // SubClassAttributes [Optional]
86                     der.skipTLVData();
87                     objectType = der.parseTLV();
88                 }
89                 if (objectType == (byte) 0xA1) { // OidDO
90                     der.parseTLV(ASN1.TAG_Sequence);
91                     context = der.saveContext();
92                     if (der.parseOID().compareTo(AC_OID) != 0) {
93                         der.restoreContext(context);
94                         der.skipTLVData();
95                     } else {
96                         return der.parsePathAttributes();
97                     }
98                 } else {
99                     throw new PKCS15Exception("[Parser] OID Tag expected");
100                 }
101             } else {
102                 der.skipTLVData();
103             }
104         }
105         return null; // No "Access Control" OID found
106     }
107 
108     /**
109      * Selects and Analyses EF_DODF file
110      *
111      * @param path Path of the "EF_DODF" file
112      * @return Path to "EF_ACMain" from "Access Control" OID; <code>null</code> otherwise
113      */
analyseFile(byte[] path)114     public byte[] analyseFile(byte[] path) throws IOException, PKCS15Exception,
115             SecureElementException {
116         Log.i(TAG, "Analysing EF_DODF...");
117 
118         if (selectFile(path) != APDU_SUCCESS) throw new PKCS15Exception("EF_DODF not found!");
119 
120         return decodeDER(readBinary(0, Util.END));
121     }
122 }
123