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 mandatory TLVs. 115 if (mRefDo == null) { 116 throw new ParserException("Missing Ref-DO in REF-AR-DO!"); 117 } 118 if (mArDo == null) { 119 throw new ParserException("Missing AR-DO in REF-AR-DO!"); 120 } 121 } 122 123 /** Tag: E2 Length: n Value: REF-DO | AR-DO: A concatenation of an REF-DO and an AR-DO. */ 124 @Override build(ByteArrayOutputStream stream)125 public void build(ByteArrayOutputStream stream) throws DO_Exception { 126 ByteArrayOutputStream temp = new ByteArrayOutputStream(); 127 128 if (mRefDo == null || mArDo == null) { 129 throw new DO_Exception("REF-AR-DO: Required DO missing!"); 130 } 131 stream.write(getTag()); 132 133 mRefDo.build(temp); 134 mArDo.build(temp); 135 136 byte[] data = temp.toByteArray(); 137 BerTlv.encodeLength(data.length, stream); 138 try { 139 stream.write(data); 140 } catch (IOException e) { 141 throw new DO_Exception("REF-AR-DO Memory IO problem! " + e.getMessage()); 142 } 143 } 144 } 145