blob: 6111cf2eeb5fea29a601bf1cf8f0a6f79a665293 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright (c) 2017, The Linux Foundation.
*/
/*
* Copyright 2012 Giesecke & Devrient GmbH.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.se.security.gpac;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* REF-AR_DO: The REF-AR-DO contains access rules inclusively its corresponding references for the
* SE application (AID reference) and device application (hash reference).
*/
public class REF_AR_DO extends BerTlv {
public static final int TAG = 0xE2;
private REF_DO mRefDo = null;
private AR_DO mArDo = null;
public REF_AR_DO(byte[] rawData, int valueIndex, int valueLength) {
super(rawData, TAG, valueIndex, valueLength);
}
public REF_AR_DO() {
super(null, TAG, 0, 0);
}
public REF_AR_DO(REF_DO refDo, AR_DO arDo) {
super(null, TAG, 0, 0);
mRefDo = refDo;
mArDo = arDo;
}
public REF_DO getRefDo() {
return mRefDo;
}
public AR_DO getArDo() {
return mArDo;
}
/**
* Interpret data.
*
* <p>Tags: E2 Length: n
*
* <p>Value: REF-DO | AR-DO: A concatenation of an REF-DO and an AR-DO. The REF-DO must
* correspond
* to the succeeding AR-DO.
*
* <p>Length: n bytes.
*/
@Override
public void interpret() throws ParserException {
mRefDo = null;
mArDo = null;
byte[] data = getRawData();
int index = getValueIndex();
if (index + getValueLength() > data.length) {
throw new ParserException("Not enough data for AR_DO!");
}
do {
BerTlv temp = BerTlv.decode(data, index);
if (temp.getTag() == REF_DO.TAG) { // REF-DO
mRefDo = new REF_DO(data, temp.getValueIndex(), temp.getValueLength());
mRefDo.interpret();
} else if (temp.getTag() == AR_DO.TAG) { // AR-DO
mArDo = new AR_DO(data, temp.getValueIndex(), temp.getValueLength());
mArDo.interpret();
} else {
// uncomment following line if a more restrictive
// behavior is necessary.
// throw new ParserException("Invalid DO in REF-AR-DO!");
}
index = temp.getValueIndex() + temp.getValueLength();
} while (getValueIndex() + getValueLength() > index);
// check for Carrier Privilege rules
if (mRefDo != null && mArDo == null && mRefDo.getAidDo() != null
&& mRefDo.getAidDo().isCarrierPrivilege()) {
return;
}
// check for mandatory TLVs.
if (mRefDo == null) {
throw new ParserException("Missing Ref-DO in REF-AR-DO!");
}
if (mArDo == null) {
throw new ParserException("Missing AR-DO in REF-AR-DO!");
}
}
/** Tag: E2 Length: n Value: REF-DO | AR-DO: A concatenation of an REF-DO and an AR-DO. */
@Override
public void build(ByteArrayOutputStream stream) throws DO_Exception {
ByteArrayOutputStream temp = new ByteArrayOutputStream();
if (mRefDo == null || mArDo == null) {
throw new DO_Exception("REF-AR-DO: Required DO missing!");
}
stream.write(getTag());
mRefDo.build(temp);
mArDo.build(temp);
byte[] data = temp.toByteArray();
BerTlv.encodeLength(data.length, stream);
try {
stream.write(data);
} catch (IOException e) {
throw new DO_Exception("REF-AR-DO Memory IO problem! " + e.getMessage());
}
}
}