Get free to work for signing
diff --git a/README.md b/README.md
index 13d0576..e47b422 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,5 @@
 
-# COSE-C Implementation [![Build Status](https://travis-ci.org/cose-wg/COSE-C.svg?branch=master)](https://travis-ci.org/cose-wg/COSE-C)
-[![Coverage Status](https://coveralls.io/repos/cose-wg/COSE-C/badge.svg?branch=master&service=github)](https://coveralls.io/github/cose-wg/COSE-C?branch=master)
+# COSE-C Implementation [![Build Status](https://travis-ci.org/cose-wg/COSE-C.svg?branch=master)](https://travis-ci.org/cose-wg/COSE-C)[![Coverage Status](https://coveralls.io/repos/cose-wg/COSE-C/badge.svg?branch=master&service=github)](https://coveralls.io/github/cose-wg/COSE-C?branch=master)
 
 This project is a C implementation of the IETF CBOR Encoded Mesage Syntax (COSE).
 There are currently two versions of the COSE document that can be read.
diff --git a/src/Cose.c b/src/Cose.c
index ff33f3b..5a0ca32 100644
--- a/src/Cose.c
+++ b/src/Cose.c
@@ -48,6 +48,8 @@
 	CHECK_CONDITION_CBOR(_COSE_array_replace(pobj, pobj->m_unprotectMap, INDEX_UNPROTECTED, CBOR_CONTEXT_PARAM_COMMA &errState), errState);
 	pobj->m_ownUnprotectedMap = false;
 
+	pobj->m_refCount = 1;
+
 	return true;
 
 errorReturn:
@@ -66,6 +68,7 @@
 #ifdef USE_CBOR_CONTEXT
 	if (context != NULL) pobj->m_allocContext = *context;
 #endif
+	pobj->m_cborRoot = pcbor;
 	pobj->m_cbor = pcbor;
 
 #ifdef TAG_IN_ARRAY
@@ -75,6 +78,11 @@
 	if (cbor->type == CN_CBOR_UINT) {
 		pobj->m_msgType = (int) cbor->v.uint;
 	}
+#else
+	//  Check if we have a tag
+	if (pcbor->type == CN_CBOR_TAG) {
+		pcbor = pobj->m_cbor = pcbor->first_child;
+	}
 #endif
 
 	pmap = _COSE_arrayget_int(pobj, INDEX_PROTECTED);
@@ -98,6 +106,7 @@
 	pobj->m_ownUnprotectedMap = false;
 
 	pobj->m_ownMsg = true;
+	pobj->m_refCount = 1;
 
 	return true;
 
@@ -115,13 +124,14 @@
 	if (pobj->m_protectedMap != NULL) CN_CBOR_FREE(pobj->m_protectedMap, context);
 	if (pobj->m_ownUnprotectedMap && (pobj->m_unprotectMap != NULL)) CN_CBOR_FREE(pobj->m_unprotectMap, context);
 	if (pobj->m_dontSendMap != NULL) CN_CBOR_FREE(pobj->m_dontSendMap, context);
-	if (pobj->m_ownMsg && (pobj->m_cbor != NULL)) CN_CBOR_FREE(pobj->m_cbor, context);
+	if (pobj->m_ownMsg && (pobj->m_cborRoot != NULL) && (pobj->m_cborRoot->parent == NULL)) CN_CBOR_FREE(pobj->m_cborRoot, context);
 }
 
 
 HCOSE COSE_Decode(const byte * rgbData, size_t cbData, int * ptype, COSE_object_type struct_type, CBOR_CONTEXT_COMMA cose_errback * perr)
 {
 	cn_cbor * cbor = NULL;
+	cn_cbor * cborRoot = NULL;
 #ifdef TAG_IN_ARRAY
 	const cn_cbor * pType = NULL;
 #endif
@@ -130,7 +140,7 @@
 
 	CHECK_CONDITION((rgbData != NULL) && (ptype != NULL), COSE_ERR_INVALID_PARAMETER);
 
-	cbor = cn_cbor_decode(rgbData, cbData, CBOR_CONTEXT_PARAM_COMMA &cbor_err);
+	cbor = cborRoot = cn_cbor_decode(rgbData, cbData, CBOR_CONTEXT_PARAM_COMMA &cbor_err);
 	CHECK_CONDITION_CBOR(cbor != NULL, cbor_err);
 
 #ifdef TAG_IN_ARRAY
@@ -167,7 +177,7 @@
 		break;
 
 	case COSE_sign_object:
-		h = (HCOSE)_COSE_Sign_Init_From_Object(cbor, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
+		h = (HCOSE)_COSE_Sign_Init_From_Object(cborRoot, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
 		if (h == NULL) {
 			goto errorReturn;
 		}
diff --git a/src/Sign.c b/src/Sign.c
index 806b30a..89f1d2c 100644
--- a/src/Sign.c
+++ b/src/Sign.c
@@ -36,12 +36,7 @@
 	if (perr == NULL) perr = &error;
 
 	if (pobj == NULL) pobj = (COSE_SignMessage *)COSE_CALLOC(1, sizeof(COSE_SignMessage), context);
-	if (pobj == NULL) {
-		perr->err = COSE_ERR_OUT_OF_MEMORY;
-	errorReturn:
-		if ((pIn == NULL) && (pobj != NULL)) COSE_FREE(pobj, context);
-		return NULL;
-	}
+	CHECK_CONDITION(pobj != NULL, COSE_ERR_OUT_OF_MEMORY);
 
 	if (!_COSE_Init_From_Object(&pobj->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
 		goto errorReturn;
@@ -50,12 +45,11 @@
 	pSigners = _COSE_arrayget_int(&pobj->m_message, INDEX_SIGNERS);
 	CHECK_CONDITION(pSigners != NULL, COSE_ERR_INVALID_PARAMETER);
 	CHECK_CONDITION(pSigners->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
+	CHECK_CONDITION(pSigners->length > 0, COSE_ERR_INVALID_PARAMETER); // Must be at least one signer
 
 	pSigners = pSigners->first_child;
-	CHECK_CONDITION(pSigners != NULL, COSE_ERR_INVALID_PARAMETER);  // Must be at least one signer
-
 	do {
-		COSE_SignerInfo * pInfo = _COSE_SignerInfo_Init_From_Object(pSigners, CBOR_CONTEXT_PARAM_COMMA perr);
+		COSE_SignerInfo * pInfo = _COSE_SignerInfo_Init_From_Object(pSigners, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
 		if (pInfo == NULL) goto errorReturn;
 
 		pInfo->m_signerNext = pobj->m_signerFirst;
@@ -64,6 +58,10 @@
 	} while (pSigners != NULL);
 
 	return(HCOSE_SIGN)pobj;
+
+errorReturn:
+	if ((pIn == NULL) && (pobj != NULL)) COSE_FREE(pobj, context);
+	return NULL;
 }
 
 bool COSE_Sign_Free(HCOSE_SIGN h)
@@ -71,25 +69,37 @@
 #ifdef USE_CBOR_CONTEXT
 	cn_cbor_context context;
 #endif
+	COSE_SignMessage * pMessage = (COSE_SignMessage *)h;
 
 	if (!IsValidSignHandle(h)) return false;
 
+	//  Check reference counting
+	if (pMessage->m_message.m_refCount > 1) {
+		pMessage->m_message.m_refCount--;
+		return true;
+	}
+
 #ifdef USE_CBOR_CONTEXT
-	context = ((COSE_SignMessage *)h)->m_message.m_allocContext;
+	context = pMessage->m_message.m_allocContext;
 #endif
 
-	_COSE_Sign_Release((COSE_SignMessage *)h);
+	_COSE_Sign_Release(pMessage);
 
-	COSE_FREE((COSE_SignMessage *)h, &context);
+	COSE_FREE(pMessage, &context);
 
 	return true;
 }
 
 void _COSE_Sign_Release(COSE_SignMessage * p)
 {
-	// if (p->pbContent != NULL) COSE_FREE(p->pbContent, &p->m_message.m_allocContext);
-	//	if (p->pbIV != NULL) COSE_FREE(p->pbIV, &p->m_message.m_allocContext);
-	// if (p->pbKey != NULL) COSE_FREE(p->pbKey, &p->m_message.m_allocContext);
+	COSE_SignerInfo * pSigner;
+	COSE_SignerInfo * pSigner2;
+
+	for (pSigner = p->m_signerFirst; pSigner != NULL; pSigner = pSigner2)
+	{
+		pSigner2 = pSigner->m_signerNext;
+		_COSE_SignerInfo_Free(pSigner);
+	}
 
 	_COSE_Release(&p->m_message);
 }
@@ -127,7 +137,6 @@
 	cn_cbor_context * context = NULL;
 #endif
 	COSE_SignMessage * pMessage = (COSE_SignMessage *)hSign;
-	COSE_SignerInfo * pSigner = NULL;
 	const cn_cbor * cbor;
 	cn_cbor * cbor2 = NULL;
 	HCOSE_SIGNER hSigner = NULL;
@@ -266,7 +275,7 @@
 	}
 
 	CHECK_CONDITION_CBOR(cn_cbor_array_append(pSigners, pSigner->m_message.m_cbor, &cbor_error), cbor_error);
-
+	pSigner->m_message.m_refCount++;
 
 	return true;
 
@@ -295,3 +304,27 @@
 	return _COSE_map_put(&((COSE_SignMessage *)h)->m_message, key, value, flags, perror);
 }
 
+HCOSE_SIGNER COSE_Sign_GetSigner(HCOSE_SIGN cose, int iSigner, cose_errback * perr)
+{
+	int i;
+	COSE_SignerInfo * p;
+
+	if (!IsValidSignHandle(cose)) {
+		if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;
+		return NULL;
+	}
+
+	p = ((COSE_SignMessage *)cose)->m_signerFirst;
+	for (i = 0; i < iSigner; i++) {
+		if (p == NULL) {
+			if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;
+			return NULL;
+		}
+		p = p->m_signerNext;
+	}
+	p->m_message.m_refCount++;
+
+	return (HCOSE_SIGNER)p;
+}
+
+
diff --git a/src/SignerInfo.c b/src/SignerInfo.c
index 5c763ea..8bbf317 100644
--- a/src/SignerInfo.c
+++ b/src/SignerInfo.c
@@ -31,57 +31,51 @@
 	return (HCOSE_SIGNER)pobj;
 }
 
-bool COSE_Signer_Free(HCOSE_SIGNER hSigner)
-{
-	if (IsValidSignerHandle(hSigner)) {
 
-		_COSE_Signer_Free((COSE_SignerInfo *)hSigner);
+bool _COSE_SignerInfo_Free(COSE_SignerInfo * pSigner)
+{
+#ifdef USE_CBOR_CONTEXT
+	cn_cbor_context context;
+#endif
+
+	//  Check ref counting
+	if (pSigner->m_message.m_refCount > 1) {
+		pSigner->m_message.m_refCount--;
 		return true;
 	}
 
-	return false;
+#ifdef USE_CBOR_CONTEXT
+	context = pSigner->m_message.m_allocContext;
+#endif
+
+	_COSE_Release(&pSigner->m_message);
+
+	COSE_FREE(pSigner, &context);
+	return true;
 }
 
-void _COSE_Signer_Free(COSE_SignerInfo * pSigner)
+bool COSE_Signer_Free(HCOSE_SIGNER hSigner)
 {
-	COSE_FREE(pSigner, &pSigner->m_message.m_allocContext);
+	COSE_SignerInfo * pSigner = (COSE_SignerInfo *)hSigner;
 
-	return;
+	if (!IsValidSignerHandle(hSigner))  return false;
+
+	return _COSE_SignerInfo_Free(pSigner);
 }
 
-
-HCOSE_SIGNER COSE_Sign_GetSigner(HCOSE_SIGN cose, int iSigner, cose_errback * perr)
+COSE_SignerInfo * _COSE_SignerInfo_Init_From_Object(cn_cbor * cbor, COSE_SignerInfo * pIn, CBOR_CONTEXT_COMMA cose_errback * perr)
 {
-	int i;
-	COSE_SignerInfo * p;
+	COSE_SignerInfo * pSigner = pIn;
 
-	if (!IsValidSignHandle(cose)) {
-		if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;
-		return NULL;
+	if (pSigner == NULL) {
+		pSigner = (COSE_SignerInfo *)COSE_CALLOC(1, sizeof(COSE_SignerInfo), context);
+		CHECK_CONDITION(pSigner != NULL, COSE_ERR_OUT_OF_MEMORY);
 	}
 
-	p = ((COSE_SignMessage *)cose)->m_signerFirst;
-	for (i = 0; i < iSigner; i++) {
-		if (p == NULL) {
-			if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;
-			return NULL;
-		}
-		p = p->m_signerNext;
-	}
-	return (HCOSE_SIGNER)p;
-}
-
-COSE_SignerInfo * _COSE_SignerInfo_Init_From_Object(cn_cbor * cbor, CBOR_CONTEXT_COMMA cose_errback * perr)
-{
-	COSE_SignerInfo * pSigner = NULL;
-
-	pSigner = (COSE_SignerInfo *)COSE_CALLOC(1, sizeof(COSE_SignerInfo), context);
-	CHECK_CONDITION(pSigner != NULL, COSE_ERR_OUT_OF_MEMORY);
-
 	CHECK_CONDITION(cbor->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
 
 	if (!_COSE_Init_From_Object(&pSigner->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
-		_COSE_Signer_Free(pSigner);
+		_COSE_SignerInfo_Free(pSigner);
 		return NULL;
 	}
 
diff --git a/src/cose_int.h b/src/cose_int.h
index b993449..d6906f0 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -8,7 +8,9 @@
 	int m_ownMsg;		//  Do I own the pointer @ m_cbor?
 	int m_ownUnprotectedMap; //  Do I own the pointer @ m_unportectedMap?
 	int m_msgType;		//  What message type is this?
+	int m_refCount;			//  Allocator Reference Counting.
 	cn_cbor * m_cbor;
+	cn_cbor * m_cborRoot;
 	cn_cbor * m_protectedMap;
 	cn_cbor * m_unprotectMap;
 	cn_cbor * m_dontSendMap;
@@ -144,8 +146,8 @@
 extern void _COSE_Sign_Release(COSE_SignMessage * p);
 
 extern bool _COSE_Signer_sign(COSE_SignerInfo * pSigner, const cn_cbor * pcborBody, const cn_cbor * pcborProtected, cose_errback * perr);
-extern COSE_SignerInfo * _COSE_SignerInfo_Init_From_Object(cn_cbor * cbor, CBOR_CONTEXT_COMMA cose_errback * perr);
-extern void _COSE_Signer_Free(COSE_SignerInfo * pSigner);
+extern COSE_SignerInfo * _COSE_SignerInfo_Init_From_Object(cn_cbor * cbor, COSE_SignerInfo * pIn, CBOR_CONTEXT_COMMA cose_errback * perr);
+extern bool _COSE_SignerInfo_Free(COSE_SignerInfo * pSigner);
 extern bool _COSE_Signer_validate(COSE_SignMessage * pSign, COSE_SignerInfo * pSigner, const byte * pbContent, size_t cbContent, const byte * pbProtected, size_t cbProtected, cose_errback * perr);
 
 //  Mac-ed items
diff --git a/test/sign.c b/test/sign.c
index cb12920..136cf47 100644
--- a/test/sign.c
+++ b/test/sign.c
@@ -73,7 +73,8 @@
 			if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) fFail = true;
 		}
 
-		// COSE_Encrypt_Free(hSig);
+		COSE_Sign_Free(hSig);
+		COSE_Signer_Free(hSigner);
 	}
 
 	if (fFailBody) {
@@ -143,6 +144,8 @@
 		if (!COSE_Signer_SetKey(hSigner, pkey, NULL)) exit(1);
 
 		if (!COSE_Sign_AddSigner(hSignObj, hSigner, NULL)) exit(1);
+
+		COSE_Signer_Free(hSigner);
 	}
 
 	if (!COSE_Sign_Sign(hSignObj, NULL)) exit(1);
@@ -151,6 +154,8 @@
 	byte * rgb = (byte *)malloc(cb);
 	cb = COSE_Encode((HCOSE)hSignObj, rgb, 0, cb);
 
+	COSE_Sign_Free(hSignObj);
+
 	int f = _ValidateSigned(pControl, rgb, cb);
 
 	free(rgb);
@@ -183,7 +188,7 @@
 	cn_cbor_mapput_int(pkey, -4, cn_cbor_data_create(rgbD, sizeof(rgbD), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
 
 	COSE_Sign_SetContent(hEncObj, (byte *) sz, strlen(sz), NULL);
-	COSE_Sign_add_signer(hEncObj, pkey, COSE_Algorithm_ECDSA_SHA_256, NULL);
+	COSE_Signer_Free(COSE_Sign_add_signer(hEncObj, pkey, COSE_Algorithm_ECDSA_SHA_256, NULL));
 
 	COSE_Sign_Sign(hEncObj, NULL);
 
@@ -191,6 +196,7 @@
 	rgb = (byte *)malloc(cb);
 	cb = COSE_Encode((HCOSE)hEncObj, rgb, 0, cb);
 
+	COSE_Sign_Free(hEncObj);
 
 	FILE * fp = fopen("test.mac.cbor", "wb");
 	fwrite(rgb, cb, 1, fp);
@@ -207,8 +213,6 @@
 	fprintf(stdout, "\r\n");
 #endif
 
-	COSE_Sign_Free(hEncObj);
-
 	/* */
 
 	int typ;