Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hashing functionality #100

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/main/java/COSE/AlgorithmID.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ public enum AlgorithmID {

RSA_PSS_256(-37, 0, 0),
RSA_PSS_384(-38, 0, 0),
RSA_PSS_512(-39, 0, 0),
RSA_PSS_512(-39, 0, 0),

SHA_512(0, 512, 0),
SHA_256(0, 256, 0),
SHA3_512(0, 512, 0),
SHA3_256(0, 256, 0)
;

private final CBORObject value;
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/COSE/HashCommon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package COSE;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public abstract class HashCommon extends Message {

protected String contextString;
protected byte[] rgbHash;

byte[] computeHash(byte[] rgbToBeSigned) throws CoseException {
AlgorithmID alg = AlgorithmID.FromCBOR(findAttribute(HeaderKeys.Algorithm));
return computeHash(alg, rgbToBeSigned);
}

protected byte[] computeHash(AlgorithmID alg, byte[] rgbToBeHashed) throws CoseException {
String algName = null;

switch (alg) {
case SHA_512:
algName = "SHA-512";
break;
case SHA_256:
algName = "SHA-256";
break;
case SHA3_512:
algName = "SHA3-512";
break;
case SHA3_256:
algName = "SHA3-256";
break;

default:
throw new CoseException("Unsupported Algorithm Specified");
}

try {
MessageDigest messageDigest = MessageDigest.getInstance(algName);
rgbHash = messageDigest.digest(rgbToBeHashed);
return rgbHash;
} catch (NoSuchAlgorithmException e) {
throw new CoseException("Hashing not possible. Unsupported Algorithm Specified");
}

}

public byte[] getHashedContent() throws CoseException {
if (rgbHash == null)
throw new CoseException("No hashed Content Specified");

return rgbHash;
}

}
132 changes: 132 additions & 0 deletions src/main/java/COSE/HashMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package COSE;

import com.upokecenter.cbor.CBORObject;
import com.upokecenter.cbor.CBORType;

public class HashMessage extends HashCommon {
/**
* Create a HashMessage object. This object corresponds to the encrypt message
* format in COSE. The leading CBOR tag will be emitted. The message content
* will be emitted.
*/
public HashMessage() {
this(true, true);
}

/**
* Create a HashMessage object. Emission of the leading tag is controlled by the
* parameter.
*
* @param emitTag emit leading tag when message is serialized
*/
public HashMessage(boolean emitTag) {
this(emitTag, true);
}

/**
* Create a HashMessage object for which the emission of the leading tag and
* content is controlled by the parameters.
*
* @param emitTag emit leading tag when message is serialized
* @param emitContent emit the content as part of the message
*/
public HashMessage(boolean emitTag, boolean emitContent) {
this.emitTag = emitTag;
this.contextString = "Hash";
this.emitContent = emitContent;
this.messageTag = MessageTag.Hash;
}

/**
* Create a hash for the message if one does not exist.
*
* @throws CoseException
*/
public void hash() throws CoseException {
if (rgbContent == null)
throw new CoseException("No Content Specified");
if (rgbHash != null)
return;

if (rgbProtected == null) {
if (objProtected.size() > 0)
rgbProtected = objProtected.EncodeToBytes();
else
rgbProtected = new byte[0];
}

CBORObject obj = CBORObject.NewArray();
obj.Add(contextString);
obj.Add(rgbProtected);
obj.Add(externalData);
obj.Add(rgbContent);

rgbHash = computeHash(rgbContent);

}

/**
* Internal function used in creating a HashMessage object from a byte string.
*
* @param messageObject HashMessage encoded object.
* @throws CoseException Errors generated by the COSE module
*/
@Override
protected void DecodeFromCBORObject(CBORObject messageObject) throws CoseException {
if (messageObject.size() != 4)
throw new CoseException("Invalid Hash structure");

if (messageObject.get(0).getType() == CBORType.ByteString) {
rgbProtected = messageObject.get(0).GetByteString();
if (messageObject.get(0).GetByteString().length == 0)
objProtected = CBORObject.NewMap();
else {
objProtected = CBORObject.DecodeFromBytes(rgbProtected);
if (objProtected.size() == 0)
rgbProtected = new byte[0];
}
} else
throw new CoseException("Invalid Hash structure");

if (messageObject.get(1).getType() == CBORType.Map) {
objUnprotected = messageObject.get(1);
} else
throw new CoseException("Invalid Hash structure");

if (messageObject.get(2).getType() == CBORType.ByteString)
rgbContent = messageObject.get(2).GetByteString();
else if (!messageObject.get(2).isNull())
throw new CoseException("Invalid Hash structure");

if (messageObject.get(3).getType() == CBORType.ByteString)
rgbHash = messageObject.get(3).GetByteString();
else
throw new CoseException("Invalid Hash structure");
}

/**
* Internal function used to create a serialization of a HashMessage
*
* @return CBOR object which can be encoded.
* @throws CoseException Errors generated by the COSE module
*/
@Override
protected CBORObject EncodeCBORObject() throws CoseException {
if (rgbHash == null)
throw new CoseException("hash function not called");
if (rgbProtected == null)
throw new CoseException("Internal Error");

CBORObject obj = CBORObject.NewArray();
obj.Add(rgbProtected);
obj.Add(objUnprotected);
if (emitContent)
obj.Add(rgbContent);
else
obj.Add(null);
obj.Add(rgbHash);

return obj;
}

}
7 changes: 6 additions & 1 deletion src/main/java/COSE/Message.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public abstract class Message extends Attribute {
* What is the plain text content of the message.
*/
protected byte[] rgbContent = null;


/**
* Decode a COSE message object. This function assumes that the message
Expand Down Expand Up @@ -108,7 +109,11 @@ else if (defaultTag != MessageTag.FromInt(messageObject.getMostInnerTag().ToInt3
case Sign:
msg = new SignMessage();
break;


case Hash:
msg = new HashMessage();
break;

default:
throw new CoseException("Message is not recognized as a COSE security Object");
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/COSE/MessageTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ public enum MessageTag {
Sign1(18),
Sign(98),
MAC(97),
MAC0(17);
MAC0(17),
Hash(20);

public final int value;

Expand Down
Loading