• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) 2017, The Linux Foundation.
18  */
19 
20 /*
21  * Copyright 2012 Giesecke & Devrient GmbH.
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 package com.android.se.security.gpac;
36 
37 import java.io.ByteArrayOutputStream;
38 import java.util.Arrays;
39 
40 /**
41  * REF-DO: The REF-DO contains a reference to uniquely assign or identify an access rule for an SE
42  * application (with an AID reference) and for a device application (with a hash reference).
43  */
44 public class REF_DO extends BerTlv {
45 
46     public static final int TAG = 0xE1;
47 
48     private AID_REF_DO mAidDo = null;
49     private Hash_REF_DO mHashDo = null;
50 
REF_DO(byte[] rawData, int valueIndex, int valueLength)51     public REF_DO(byte[] rawData, int valueIndex, int valueLength) {
52         super(rawData, TAG, valueIndex, valueLength);
53     }
54 
REF_DO(AID_REF_DO aidRefDo, Hash_REF_DO hashRefDo)55     public REF_DO(AID_REF_DO aidRefDo, Hash_REF_DO hashRefDo) {
56         super(null, TAG, 0, 0);
57         mAidDo = aidRefDo;
58         mHashDo = hashRefDo;
59     }
60 
61     @Override
toString()62     public String toString() {
63         StringBuilder b = new StringBuilder();
64         b.append("REF_DO: ");
65         if (mAidDo != null) {
66             b.append(mAidDo.toString());
67             b.append(' ');
68         }
69         if (mHashDo != null) {
70             b.append(mHashDo.toString());
71         }
72         return b.toString();
73     }
74 
getAidDo()75     public AID_REF_DO getAidDo() {
76         return mAidDo;
77     }
78 
getHashDo()79     public Hash_REF_DO getHashDo() {
80         return mHashDo;
81     }
82 
83     /**
84      * Interpret data.
85      *
86      * <p>Tags: E1 -> Length: n
87      *
88      * <p>Value: AID-REF-DO | Hash-REF-DO: A concatenation of an AID-REF-DO and a Hash-REF-DO.
89      *
90      * <p>Length: n bytes.
91      */
92     @Override
interpret()93     public void interpret() throws ParserException {
94 
95         mAidDo = null;
96         mHashDo = null;
97 
98         byte[] data = getRawData();
99         int index = getValueIndex();
100 
101         if (index + getValueLength() > data.length) {
102             throw new ParserException("Not enough data for AR_DO!");
103         }
104 
105         do {
106             BerTlv temp = BerTlv.decode(data, index);
107 
108             if (temp.getTag() == AID_REF_DO.TAG
109                     || temp.getTag() == AID_REF_DO.TAG_DEFAULT_APPLICATION) { // AID-REF-DO
110                 mAidDo = new AID_REF_DO(data, temp.getTag(), temp.getValueIndex(),
111                         temp.getValueLength());
112                 mAidDo.interpret();
113             } else if (temp.getTag() == Hash_REF_DO.TAG) { // Hash-REF-DO
114                 mHashDo = new Hash_REF_DO(data, temp.getValueIndex(), temp.getValueLength());
115                 mHashDo.interpret();
116             } else {
117                 // uncomment following line if a more restrictive
118                 // behaviour is necessary.
119                 // throw new ParserException("Invalid DO in REF-DO!");
120             }
121             index = temp.getValueIndex() + temp.getValueLength();
122         } while (getValueIndex() + getValueLength() > index);
123 
124         // A rule without AID is a Carrier Privilege Rule.
125         // Enforces the AID to be the Carrier Privilege AID to avoid a null AID.
126         if (mAidDo == null && mHashDo != null) {
127             mAidDo = AID_REF_DO.createCarrierPrivilegeAid();
128         }
129 
130         // check if there is a AID-REF-DO
131         if (mAidDo == null) {
132             throw new ParserException("Missing AID-REF-DO in REF-DO!");
133         }
134         // check if there is a Hash-REF-DO
135         if (mHashDo == null) {
136             throw new ParserException("Missing Hash-REF-DO in REF-DO!");
137         }
138     }
139 
140     /**
141      * Tag: E1 Length: n Value: AID-REF-DO | Hash-REF-DO: A concatenation of an AID-REF-DO and a
142      * Hash-REF-DO.
143      */
144     @Override
build(ByteArrayOutputStream stream)145     public void build(ByteArrayOutputStream stream) throws DO_Exception {
146         ByteArrayOutputStream temp = new ByteArrayOutputStream();
147 
148         if (mAidDo == null || mHashDo == null) {
149             throw new DO_Exception("REF-DO: Required DO missing!");
150         }
151 
152         mAidDo.build(temp);
153         mHashDo.build(temp);
154 
155         byte[] data = temp.toByteArray();
156         BerTlv tlv = new BerTlv(data, getTag(), 0, data.length);
157         tlv.build(stream);
158     }
159 
160     @Override
equals(Object obj)161     public boolean equals(Object obj) {
162         if (obj instanceof REF_DO) {
163             REF_DO ref_do = (REF_DO) obj;
164             if (getTag() == ref_do.getTag()) {
165                 if (AID_REF_DO.equals(mAidDo, ref_do.mAidDo)) {
166                     if (Hash_REF_DO.equals(mHashDo, ref_do.mHashDo)) {
167                         return true;
168                     }
169                 }
170             }
171         }
172         return false;
173     }
174 
175     @Override
hashCode()176     public int hashCode() {
177         ByteArrayOutputStream stream = new ByteArrayOutputStream();
178         try {
179             this.build(stream);
180         } catch (DO_Exception e) {
181             return 1;
182         }
183         byte[] data = stream.toByteArray();
184         int hash = Arrays.hashCode(data);
185         // int hash = data.hashCode();
186         return hash;
187     }
188 
isCarrierPrivilegeRefDo()189     public boolean isCarrierPrivilegeRefDo() {
190         return (mAidDo != null && mAidDo.isCarrierPrivilege());
191     }
192 }
193