Home | History | Annotate | Download | only in gpac
      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 import java.util.Arrays;
     40 
     41 /**
     42  * Hash-REF-DO: The Hash-REF-DO is used for retrieving and storing the corresponding access rules
     43  * for a device application (which is identified by the hash value of its certificate) from and to
     44  * the ARA
     45  */
     46 public class Hash_REF_DO extends BerTlv {
     47 
     48     public static final int TAG = 0xC1;
     49     public static final int SHA1_LEN = 20;
     50 
     51     private byte[] mHash = new byte[0];
     52 
     53     public Hash_REF_DO(byte[] rawData, int valueIndex, int valueLength) {
     54         super(rawData, TAG, valueIndex, valueLength);
     55     }
     56 
     57     public Hash_REF_DO(byte[] hash) {
     58         super(hash, TAG, 0, (hash == null ? 0 : hash.length));
     59         if (hash != null) mHash = hash;
     60     }
     61 
     62     public Hash_REF_DO() {
     63         super(null, TAG, 0, 0);
     64     }
     65 
     66     /**
     67      * Comapares two Hash_REF_DO objects and returns true if they are equal
     68      */
     69     public static boolean equals(Hash_REF_DO obj1, Hash_REF_DO obj2) {
     70         if (obj1 == null) {
     71             return (obj2 == null) ? true : false;
     72         }
     73         return obj1.equals(obj2);
     74     }
     75 
     76     public byte[] getHash() {
     77         return mHash;
     78     }
     79 
     80     @Override
     81     public String toString() {
     82         StringBuilder b = new StringBuilder();
     83         ByteArrayOutputStream out = new ByteArrayOutputStream();
     84         b.append("Hash_REF_DO: ");
     85         try {
     86             this.build(out);
     87             b.append(BerTlv.toHex(out.toByteArray()));
     88         } catch (Exception e) {
     89             b.append(e.getLocalizedMessage());
     90         }
     91         return b.toString();
     92     }
     93 
     94     /**
     95      * Tags: C1 Length: 0 or SHA1_LEN bytes
     96      *
     97      * <p>Value: Hash: identifies a specific device application Empty: refers to all device
     98      * applications
     99      *
    100      * <p>Length: SHA1_LEN for 20 bytes SHA-1 hash value 0 for empty value field
    101      */
    102     @Override
    103     public void interpret() throws ParserException {
    104 
    105         mHash = new byte[0];
    106 
    107         byte[] data = getRawData();
    108         int index = getValueIndex();
    109 
    110         // sanity checks
    111         if (getValueLength() != 0 && getValueLength() != SHA1_LEN) {
    112             throw new ParserException("Invalid value length for Hash-REF-DO!");
    113         }
    114 
    115         if (getValueLength() == SHA1_LEN) {
    116             if (index + getValueLength() > data.length) {
    117                 throw new ParserException("Not enough data for Hash-REF-DO!");
    118             }
    119 
    120             mHash = new byte[getValueLength()];
    121             System.arraycopy(data, index, mHash, 0, getValueLength());
    122         }
    123     }
    124 
    125     /**
    126      * Tags: C1 Length: 0 or 20 bytes
    127      *
    128      * <p>Value: Hash: identifies a specific device application Empty: refers to all device
    129      * applications
    130      *
    131      * <p>Length: SHA1_LEN for 20 bytes SHA-1 hash value 0 for empty value field
    132      */
    133     @Override
    134     public void build(ByteArrayOutputStream stream) throws DO_Exception {
    135 
    136         // sanity checks
    137         if (!(mHash.length != SHA1_LEN || mHash.length != 0)) {
    138             throw new DO_Exception("Hash value must be " + SHA1_LEN + " bytes in length!");
    139         }
    140 
    141         stream.write(getTag());
    142 
    143         try {
    144             stream.write(mHash.length);
    145             stream.write(mHash);
    146         } catch (IOException ioe) {
    147             throw new DO_Exception("Hash could not be written!");
    148         }
    149     }
    150 
    151     @Override
    152     public boolean equals(Object obj) {
    153         if (obj instanceof Hash_REF_DO) {
    154             Hash_REF_DO hash_ref_do = (Hash_REF_DO) obj;
    155             if (getTag() == hash_ref_do.getTag()) {
    156                 return Arrays.equals(mHash, hash_ref_do.mHash);
    157             }
    158         }
    159         return false;
    160     }
    161 }
    162