| /* |
| * 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; |
| import java.util.Arrays; |
| |
| /** |
| * The AID-REF-DO is used for retrieving and storing the corresponding access rules for an SE |
| * application (which is identified by its AID) from and to the ARA. Two different AID reference |
| * data objects exist and one of these can be chosen and applied for a GET DATA and STORE DATA |
| * command |
| */ |
| public class AID_REF_DO extends BerTlv { |
| |
| public static final int TAG = 0x4F; |
| public static final int TAG_DEFAULT_APPLICATION = 0xC0; |
| |
| private static final byte[] CARRIER_PRIVILEGE_AID = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, |
| (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; |
| private byte[] mAid = new byte[0]; |
| |
| public AID_REF_DO(byte[] rawData, int tag, int valueIndex, int valueLength) { |
| super(rawData, tag, valueIndex, valueLength); |
| } |
| |
| public AID_REF_DO(int tag, byte[] aid) { |
| super(aid, tag, 0, (aid == null ? 0 : aid.length)); |
| if (aid != null) mAid = aid; |
| } |
| |
| public AID_REF_DO(int tag) { |
| super(null, tag, 0, 0); |
| } |
| |
| /** |
| * Comapares two AID_REF_DO objects and returns true if they are equal |
| */ |
| public static boolean equals(AID_REF_DO obj1, AID_REF_DO obj2) { |
| if (obj1 == null) { |
| return (obj2 == null) ? true : false; |
| } |
| return obj1.equals(obj2); |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder b = new StringBuilder(); |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| b.append("AID_REF_DO: "); |
| try { |
| this.build(out); |
| b.append(BerTlv.toHex(out.toByteArray())); |
| } catch (Exception e) { |
| b.append(e.getLocalizedMessage()); |
| } |
| return b.toString(); |
| } |
| |
| public byte[] getAid() { |
| return mAid; |
| } |
| |
| /** |
| * Tags: C0 -> Length: 0 -> Default selected application (all channels) 4F -> Length: 0 or 5 - |
| * 16 |
| * bytes |
| * |
| * <p>Value: AID: identifies a specific application Empty: refers to all SE applications |
| * |
| * <p>Length: 5-16 for an AID according to ISO/IEC7816-5 0 for empty value field |
| */ |
| @Override |
| public void interpret() throws ParserException { |
| byte[] data = getRawData(); |
| int index = getValueIndex(); |
| |
| if (getTag() == TAG_DEFAULT_APPLICATION) { |
| if (getValueLength() != 0) { |
| throw new ParserException("Invalid value length for AID-REF-DO!"); |
| } |
| } else if (getTag() == TAG) { |
| |
| // quick checks |
| if ((getValueLength() < 5 || getValueLength() > 16) && getValueLength() != 0) { |
| throw new ParserException("Invalid value length for AID-REF-DO!"); |
| } |
| |
| if (index + getValueLength() > data.length) { |
| throw new ParserException("Not enough data for AID-REF-DO!"); |
| } |
| |
| mAid = new byte[getValueLength()]; |
| System.arraycopy(data, index, mAid, 0, getValueLength()); |
| |
| } else { |
| throw new ParserException("Invalid Tag for AID-REF-DO!"); |
| } |
| } |
| |
| /** |
| * Tags: C0 -> Length: 0 -> Default selected application (all channels) 4F -> Length: 0 or 5 - |
| * 16 |
| * bytes |
| * |
| * <p>Value: AID: identifies a specific application Empty: refers to all SE applications |
| * |
| * <p>Length: 5-16 for an AID according to ISO/IEC7816-5 0 for empty value field |
| */ |
| @Override |
| public void build(ByteArrayOutputStream stream) throws DO_Exception { |
| |
| if (getTag() == TAG_DEFAULT_APPLICATION) { |
| if (mAid.length > 0) { |
| throw new DO_Exception("No value allowed for default selected application!"); |
| } |
| stream.write(getTag()); |
| stream.write(0x00); |
| } else if (getTag() == TAG) { |
| |
| // quick check |
| if (getValueLength() != 0) { |
| if (getValueLength() < 5 || getValueLength() > 16) { |
| throw new DO_Exception("Invalid length of AID!"); |
| } |
| } |
| |
| stream.write(getTag()); |
| stream.write(mAid.length); |
| try { |
| stream.write(mAid); |
| } catch (IOException ioe) { |
| throw new DO_Exception("AID could not be written!"); |
| } |
| } else { |
| throw new DO_Exception("AID-REF-DO must either be C0 or 4F!"); |
| } |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (obj instanceof AID_REF_DO) { |
| AID_REF_DO aid_ref_do = (AID_REF_DO) obj; |
| if (getTag() == aid_ref_do.getTag()) { |
| return Arrays.equals(mAid, aid_ref_do.mAid); |
| } |
| } |
| return false; |
| } |
| |
| /** Checks if the AID_REF_DO is a Carrier Privilege rule */ |
| public boolean isCarrierPrivilege() { |
| return Arrays.equals(mAid, CARRIER_PRIVILEGE_AID); |
| } |
| |
| /** Creates a Carrier Privilege AID_REF_DO */ |
| public static AID_REF_DO createCarrierPrivilegeAid() { |
| return new AID_REF_DO(AID_REF_DO.TAG, CARRIER_PRIVILEGE_AID); |
| } |
| } |