Attribute.java
/*******************************************************************************
* Original from https://github.com/cose-wg/COSE-JAVA Commit 1a20373
*
* Copyright (c) 2016, Jim Schaad
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of COSE-JAVA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* Achim Kraus (Bosch Software Innovations GmbH) - update to cbor 4.0.0
* align with cose 1.0
* commit 629912b94ea80c4c6
******************************************************************************/
package org.eclipse.californium.cose;
import com.upokecenter.cbor.*;
/**
* Internal class which supports the protected and unprotected attribute maps that
* are common to the core COSE objects.
* <p>
* In addition an attribute map is provided
* for attributes which will not be sent as part of the message, but which are needed
* for the code to function correctly. As an example of how this works, there are
* some situations where the algorithm identifier is not sent as part of an encrypted message,
* however it is needed in order to encrypt or decrypt the content so the application would set it
* in the unsent package at send time - for encryption - or at receive time - for decryption.
*
* @author jimsch
*/
public class Attribute {
/**
* Internal map of protected attributes
*/
protected CBORObject objProtected = CBORObject.NewMap();
/**
* Internal map of unprotected attributes
*/
protected CBORObject objUnprotected = CBORObject.NewMap();
/**
* Internal map of attributes which are not a part of the encoded message.
*/
protected CBORObject objDontSend = CBORObject.NewMap();
/**
* The encoded byte string for the protected attributes. If this variable is
* set then the message was either decoded or as been cryptographically signed/encrypted/maced.
* If it is set, then do not allow objProtected to be modified.
*/
protected byte[] rgbProtected;
/**
* Holder for the external data object that is authenticated as part of the
* message
*/
protected byte[] externalData = new byte[0];
/**
* Used to place an attribute in the protected attribute map
* Attributes placed in this map are part of the integrity check if the cryptographic algorithm supports authenticated data.
* @deprecated As of COSE 0.9.1, use Attribute.PROTECT
*/
@Deprecated
public static final int ProtectedAttributes = 1;
/**
* Used to place an attribute in the unprotected attribute map
* Attributes placed in this map are not integrity protected.
*
* @deprecated As of COSE 0.9.1, use Attribute.UNPROTECT
*/
@Deprecated
public static final int UnprotectedAttributes = 2;
/**
* Used to place an attribute in the do not send attribute map
* Attributes in this map are available for lookup and use but will not
* be transmitted as part of the message.
*
* @deprecated As of COSE 0.9.1, use Attribute.DO_NOT_SEND
*/
@Deprecated
public static final int DontSendAttributes = 4;
/**
* Used to place an attribute in the protected attribute map
* Attributes placed in this map are part of the integrity check if the cryptographic algorithm supports authenticated data.
*/
public static final int PROTECTED = 1;
/**
* Used to place an attribute in the unprotected attribute map
* Attributes placed in this map are not integrity protected.
*/
public static final int UNPROTECTED = 2;
/**
* Used to place an attribute in the do not send attribute map
* Attributes in this map are available for lookup and use but will not
* be transmitted as part of the message.
*/
public static final int DO_NOT_SEND = 4;
/**
* Set an attribute in the COSE object.
* Setting an attribute in one map will remove it from all other maps as a side effect.
*
* @param label CBOR object which identifies the attribute in the map
* @param value CBOR object which contains the value of the attribute
* @param where Identifies which of the buckets to place the attribute in.
* ProtectedAttributes - attributes cryptographically protected
* UnprotectedAttributes - attributes not cryptographically protected
* DontSendAttributes - attributes used locally and not transmitted
* @exception CoseException COSE Package exception
*/
public void addAttribute(CBORObject label, CBORObject value, int where) throws CoseException {
removeAttribute(label);
if ((label.getType() != CBORType.Integer) && (label.getType() != CBORType.TextString)) {
throw new CoseException("Labels must be integers or strings");
}
switch (where) {
case PROTECTED:
if (rgbProtected != null) throw new CoseException("Cannot modify protected attribute if signature has been computed");
objProtected.Add(label, value);
break;
case UNPROTECTED:
objUnprotected.Add(label, value);
break;
case DO_NOT_SEND:
objDontSend.Add(label, value);
break;
default:
throw new CoseException("Invalid attribute location given");
}
}
/**
* Set an attribute in the COSE object.
* Setting an attribute in one map will remove it from all other maps as a side effect.
*
* @param label HeaderKeys label which identifies the attribute in the map
* @param value CBOR object which contains the value of the attribute
* @param where Identifies which of the buckets to place the attribute in.
* ProtectedAttributes - attributes cryptographically protected
* UnprotectedAttributes - attributes not cryptographically protected
* DontSendAttributes - attributes used locally and not transmitted
* @exception CoseException COSE Package exception
*/
public void addAttribute(HeaderKeys label, CBORObject value, int where) throws CoseException {
addAttribute(label.AsCBOR(), value, where);
}
/**
* Set an attribute in the COSE object.
* Setting an attribute in one map will remove it from all other maps as a side effect.
*
* @param label HeaderKeys label which identifies the attribute in the map
* @param value CBOR object which contains the value of the attribute
* @param where Identifies which of the buckets to place the attribute in.
* ProtectedAttributes - attributes cryptographically protected
* UnprotectedAttributes - attributes not cryptographically protected
* DontSendAttributes - attributes used locally and not transmitted
* @exception CoseException COSE Package exception
*/
public void addAttribute(HeaderKeys label, byte[] value, int where) throws CoseException {
addAttribute(label.AsCBOR(), CBORObject.FromObject(value), where);
}
/**
* Set an attribute in the protect bucket of the COSE object
*
* @param label CBOR object which identifies the attribute in the map
* @param value CBOR object which contains the value of the attribute
*
* @deprecated As of COSE 0.9.0, use addAttribute(CBORObject, CBORObject, Attribute.PROTECTED);
* @exception CoseException COSE Package exception
*/
@Deprecated
public void AddProtected(CBORObject label, CBORObject value) throws CoseException {
addAttribute(label, value, PROTECTED);
}
/**
* Set an attribute in the protect bucket of the COSE object
*
* @param label HeaderKeys label which identifies the attribute in the map
* @param value CBOR object which contains the value of the attribute
*
* @deprecated As of COSE 0.9.0, use addAttribute(HeaderKeys, CBORObject, Attribute.PROTECTED);
* @exception CoseException COSE Package exception
*/
@Deprecated
public void AddProtected(HeaderKeys label, CBORObject value) throws CoseException {
addAttribute(label, value, PROTECTED);
}
/**
* Set an attribute in the protect bucket of the COSE object
*
* @param label CBOR object which identifies the attribute in the map
* @param value byte array of value
*
* @deprecated As of COSE 0.9.0, use addAttribute(HeaderKeys, byte[], Attribute.PROTECTED);
* @exception CoseException COSE Package exception
*/
@Deprecated
public void AddProtected(HeaderKeys label, byte[] value) throws CoseException {
addAttribute(label, value, PROTECTED);
}
/**
* Set an attribute in the unprotected bucket of the COSE object
*
* @param label value identifies the attribute in the map
* @param value value to be associated with the label
*
* @deprecated As of COSE 0.9.1, use addAttribute(HeaderKeys, byte[], Attribute.UNPROTECTED);
* @exception CoseException COSE Package exception
*/
@Deprecated
public void AddUnprotected(CBORObject label, CBORObject value) throws CoseException {
addAttribute(label, value, UNPROTECTED);
}
/**
* Set an attribute in the unprotected bucket of the COSE object
*
* @param label identifies the attribute in the map
* @param value value to be associated with the label
*
* @deprecated As of COSE 0.9.1, use addAttribute(HeaderKeys, byte[], Attribute.UNPROTECTED);
* @exception CoseException COSE Package exception
*/
@Deprecated
public void AddUnprotected(HeaderKeys label, CBORObject value) throws CoseException {
addAttribute(label, value, UNPROTECTED);
}
/**
* Set an attribute in the unprotected bucket of the COSE object
*
* @param label identifies the attribute in the map
* @param value value to be associated with the label
*
* @deprecated As of COSE 0.9.1, use addAttribute(HeaderKeys, byte[], Attribute.UNPROTECTED);
* @exception CoseException COSE Package exception
*/
@Deprecated
public void AddUnprotected(HeaderKeys label, byte[] value) throws CoseException {
addAttribute(label, value, UNPROTECTED);
}
/**
* Locate an attribute in one of the attribute buckets The buckets are
* searched in the order protected, unprotected, unsent.
*
* @param label - Label of the value to be searched for
* @return - CBORObject with the value if found; otherwise null
*/
public CBORObject findAttribute(CBORObject label) {
return findAttribute(label, PROTECTED | UNPROTECTED | DO_NOT_SEND);
}
/**
* Locate an attribute in one of the attribute buckets The buckets are
* searched in the order protected, unprotected, unsent.
*
* @param label - HeaderKey enumeration value to search for
* @param where which maps to search for the label
* @return - CBORObject with the value if found; otherwise null
*/
public CBORObject findAttribute(CBORObject label, int where) {
if (((where & PROTECTED) == PROTECTED) && objProtected.ContainsKey(label)) return objProtected.get(label);
if (((where & UNPROTECTED) == UNPROTECTED) && objUnprotected.ContainsKey(label)) return objUnprotected.get(label);
if (((where & DO_NOT_SEND) == DO_NOT_SEND) && objDontSend.ContainsKey(label)) return objDontSend.get(label);
return null;
}
/**
* Locate an attribute in one of the attribute buckets The buckets are
* searched in the order protected, unprotected, unsent.
*
* @param label - HeaderKey enumeration value to search for
* @return - CBORObject with the value if found; otherwise null
*/
public CBORObject findAttribute(HeaderKeys label) {
return findAttribute(label.AsCBOR(), PROTECTED | UNPROTECTED | DO_NOT_SEND);
}
/**
* Locate an attribute in one of the attribute buckets The buckets are
* searched in the order protected, unprotected, unsent.
*
* @param label - HeaderKey enumeration value to search for
* @param where which maps to search for the label
* @return - CBORObject with the value if found; otherwise null
*/
public CBORObject findAttribute(HeaderKeys label, int where) {
return findAttribute(label.AsCBOR(), where);
}
/**
* Return the entire map of protected attributes
*
* @return the protected attribute map
*/
public CBORObject getProtectedAttributes() {
return objProtected;
}
/**
* Return the entire map of unprotected attributes
*
* @return the unprotected attribute map
*/
public CBORObject getUnprotectedAttributes() {
return objUnprotected;
}
/**
* Return the entire map of do not send attributes
*
* @return the do not send attribute map
*/
public CBORObject getDoNotSendAttributes() {
return objDontSend;
}
/**
* Remove an attribute from the set of all attribute maps.
*
* @param label attribute to be removed
* @exception CoseException if integrity protection would be modified.
*/
public void removeAttribute(CBORObject label) throws CoseException {
if (objProtected.ContainsKey(label)) {
if (rgbProtected != null) throw new CoseException("Operation would modify integrity protected attributes");
objProtected.Remove(label);
}
if (objUnprotected.ContainsKey(label)) objUnprotected.Remove(label);
if (objDontSend.ContainsKey(label)) objDontSend.Remove(label);
}
/**
* Remove an attribute from the set of all attribute maps.
*
* @param label attribute to be removed
* @throws CoseException - Label not present
*/
public void removeAttribute(HeaderKeys label) throws CoseException {
removeAttribute(label.AsCBOR());
}
/**
* Get the optional external data field to be authenticated
*
* @return external authenticated data
*/
public byte[] getExternal() {
return externalData;
}
/**
* Set the optional external data field to be authenticated
*
* @param rgbData - data to be authenticated
*/
public void setExternal(byte[] rgbData) {
if (rgbData == null) rgbData = new byte[0];
externalData = rgbData;
}
}