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.io.IOException; 39 40 /** 41 * REF-AR_DO: The REF-AR-DO contains access rules inclusively its corresponding references for the 42 * SE application (AID reference) and device application (hash reference). 43 */ 44 public class REF_AR_DO extends BerTlv { 45 46 public static final int TAG = 0xE2; 47 48 private REF_DO mRefDo = null; 49 private AR_DO mArDo = null; 50 REF_AR_DO(byte[] rawData, int valueIndex, int valueLength)51 public REF_AR_DO(byte[] rawData, int valueIndex, int valueLength) { 52 super(rawData, TAG, valueIndex, valueLength); 53 } 54 REF_AR_DO()55 public REF_AR_DO() { 56 super(null, TAG, 0, 0); 57 } 58 REF_AR_DO(REF_DO refDo, AR_DO arDo)59 public REF_AR_DO(REF_DO refDo, AR_DO arDo) { 60 super(null, TAG, 0, 0); 61 mRefDo = refDo; 62 mArDo = arDo; 63 } 64 getRefDo()65 public REF_DO getRefDo() { 66 return mRefDo; 67 } 68 getArDo()69 public AR_DO getArDo() { 70 return mArDo; 71 } 72 73 /** 74 * Interpret data. 75 * 76 * <p>Tags: E2 Length: n 77 * 78 * <p>Value: REF-DO | AR-DO: A concatenation of an REF-DO and an AR-DO. The REF-DO must 79 * correspond 80 * to the succeeding AR-DO. 81 * 82 * <p>Length: n bytes. 83 */ 84 @Override interpret()85 public void interpret() throws ParserException { 86 87 mRefDo = null; 88 mArDo = null; 89 90 byte[] data = getRawData(); 91 int index = getValueIndex(); 92 93 if (index + getValueLength() > data.length) { 94 throw new ParserException("Not enough data for AR_DO!"); 95 } 96 97 do { 98 BerTlv temp = BerTlv.decode(data, index); 99 if (temp.getTag() == REF_DO.TAG) { // REF-DO 100 mRefDo = new REF_DO(data, temp.getValueIndex(), temp.getValueLength()); 101 mRefDo.interpret(); 102 } else if (temp.getTag() == AR_DO.TAG) { // AR-DO 103 mArDo = new AR_DO(data, temp.getValueIndex(), temp.getValueLength()); 104 mArDo.interpret(); 105 } else { 106 107 // uncomment following line if a more restrictive 108 // behavior is necessary. 109 // throw new ParserException("Invalid DO in REF-AR-DO!"); 110 } 111 index = temp.getValueIndex() + temp.getValueLength(); 112 } while (getValueIndex() + getValueLength() > index); 113 114 // check for Carrier Privilege rules 115 if (mRefDo != null && mArDo == null && mRefDo.getAidDo() != null 116 && mRefDo.getAidDo().isCarrierPrivilege()) { 117 return; 118 } 119 120 // check for mandatory TLVs. 121 if (mRefDo == null) { 122 throw new ParserException("Missing Ref-DO in REF-AR-DO!"); 123 } 124 if (mArDo == null) { 125 throw new ParserException("Missing AR-DO in REF-AR-DO!"); 126 } 127 } 128 129 /** Tag: E2 Length: n Value: REF-DO | AR-DO: A concatenation of an REF-DO and an AR-DO. */ 130 @Override build(ByteArrayOutputStream stream)131 public void build(ByteArrayOutputStream stream) throws DO_Exception { 132 ByteArrayOutputStream temp = new ByteArrayOutputStream(); 133 134 if (mRefDo == null || mArDo == null) { 135 throw new DO_Exception("REF-AR-DO: Required DO missing!"); 136 } 137 stream.write(getTag()); 138 139 mRefDo.build(temp); 140 mArDo.build(temp); 141 142 byte[] data = temp.toByteArray(); 143 BerTlv.encodeLength(data.length, stream); 144 try { 145 stream.write(data); 146 } catch (IOException e) { 147 throw new DO_Exception("REF-AR-DO Memory IO problem! " + e.getMessage()); 148 } 149 } 150 } 151