Create and validate the signature test cases
diff --git a/src/Sign.c b/src/Sign.c
index 8417ee8..fbf97bd 100644
--- a/src/Sign.c
+++ b/src/Sign.c
@@ -47,7 +47,7 @@
goto errorReturn;
}
- pSigners = _COSE_arrayget_int(&pobj->m_message, INDEX_SIGNATURES);
+ 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);
@@ -116,11 +116,7 @@
p = cn_cbor_data_create(rgb, (int) cb, CBOR_CONTEXT_PARAM_COMMA NULL);
CHECK_CONDITION(p != NULL, COSE_ERR_OUT_OF_MEMORY);
-#ifdef USE_ARRAY
CHECK_CONDITION(_COSE_array_replace(&pMessage->m_message, p, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_OUT_OF_MEMORY);
-#else
- CHECK_CONDITION(cn_cbor_mapput_int(pMessage->m_message.m_cbor, COSE_Header_Ciphertext, p, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_OUT_OF_MEMORY);
-#endif
return true;
}
@@ -177,25 +173,15 @@
pSigner->m_signerNext = pMessage->m_signerFirst;
pMessage->m_signerFirst = pSigner;
-#ifdef USE_ARRAY
- cn_cbor * pSigners = cn_cbor_index(pMessage->m_message.m_cbor, INDEX_SIGNATURES+1); // M00BUG
-#else
- cn_cbor * pSigners = (cn_cbor *)cn_cbor_mapget_int(pMessage->m_message.m_cbor, COSE_Header_Signers);
-#endif
+ cn_cbor * pSigners = cn_cbor_index(pMessage->m_message.m_cbor, INDEX_SIGNERS); // M00BUG
+
if (pSigners == NULL) {
pSigners = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA NULL);
CHECK_CONDITION(pSigners != NULL, COSE_ERR_OUT_OF_MEMORY);
-#ifdef USE_ARRAY
- if (!_COSE_array_replace(&pMessage->m_message, pSigners, INDEX_SIGNATURES, CBOR_CONTEXT_PARAM_COMMA NULL)) {
+ if (!_COSE_array_replace(&pMessage->m_message, pSigners, INDEX_SIGNERS, CBOR_CONTEXT_PARAM_COMMA NULL)) {
CN_CBOR_FREE(pSigners, context);
CHECK_CONDITION(false, COSE_ERR_CBOR);
}
-#else
- if (!cn_cbor_mapput_int(pMessage->m_message.m_cbor, COSE_Header_Signers, pSigners, CBOR_CONTEXT_PARAM_COMMA NULL)) {
- CN_CBOR_FREE(pSigners, context);
- CHECK_CONDITION(false, COSE_ERR_CBOR);
- }
-#endif
}
CHECK_CONDITION(cn_cbor_array_append(pSigners, pSigner->m_message.m_cbor, NULL), COSE_ERR_CBOR);
@@ -222,14 +208,8 @@
// context = &pMessage->m_message.m_allocContext;
#endif
-#ifdef USE_ARRAY
pcborBody = _COSE_arrayget_int(&pMessage->m_message, INDEX_BODY);
CHECK_CONDITION((pcborBody != NULL) && (pcborBody->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
-#else
- // From this layer we use the protected fields and the body
- pcborBody = cn_cbor_mapget_int(pMessage->m_message.m_cbor, COSE_Header_Ciphertext);
- CHECK_CONDITION(pcborBody != NULL, COSE_ERR_INVALID_PARAMETER);
-#endif
pcborProtected = _COSE_encode_protected(&pMessage->m_message, perr);
if (pcborProtected == NULL) goto errorReturn;
@@ -268,3 +248,69 @@
errorReturn:
return false;
}
+
+
+bool COSE_Sign_AddSigner(HCOSE_SIGN hSign, HCOSE_SIGNER hSigner, cose_errback * perr)
+{
+ COSE_SignerInfo * pSigner;
+ COSE_SignMessage * pSign;
+ cn_cbor * pSigners = NULL;
+ cn_cbor * pSignersT = NULL;
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = NULL;
+#endif
+ cn_cbor_errback cbor_error;
+
+ CHECK_CONDITION(IsValidSignHandle(hSign), COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_PARAMETER);
+
+ pSign = (COSE_SignMessage *)hSign;
+ pSigner = (COSE_SignerInfo *)hSigner;
+
+ pSigner->m_signerNext = pSign->m_signerFirst;
+ pSign->m_signerFirst = pSigner;
+
+#ifdef USE_CBOR_CONTEXT
+ context = &pSign->m_message.m_allocContext;
+#endif // USE_CBOR_CONTEXT
+
+ pSigners = _COSE_arrayget_int(&pSign->m_message, INDEX_SIGNERS);
+ if (pSigners == NULL) {
+ pSignersT = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(pSignersT != NULL, cbor_error);
+
+ CHECK_CONDITION_CBOR(_COSE_array_replace(&pSign->m_message, pSignersT, INDEX_SIGNERS, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
+ pSigners = pSignersT;
+ pSignersT = NULL;
+ }
+
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pSigners, pSigner->m_message.m_cbor, &cbor_error), cbor_error);
+
+
+ return true;
+
+errorReturn:
+ if (pSignersT == NULL) CN_CBOR_FREE(pSignersT, context);
+ return false;
+}
+
+cn_cbor * COSE_Sign_map_get_int(HCOSE_SIGN h, int key, int flags, cose_errback * perror)
+{
+ if (!IsValidSignHandle(h)) {
+ if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ return _COSE_map_get_int(&((COSE_SignMessage *)h)->m_message, key, flags, perror);
+}
+
+bool COSE_Sign_map_put(HCOSE_SIGN h, int key, cn_cbor * value, int flags, cose_errback * perror)
+{
+ if (!IsValidSignHandle(h) || (value == NULL)) {
+ if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
+ return false;
+ }
+
+ return _COSE_map_put(&((COSE_SignMessage *)h)->m_message, key, value, flags, perror);
+}
+
diff --git a/src/SignerInfo.c b/src/SignerInfo.c
index 8a5079a..5c763ea 100644
--- a/src/SignerInfo.c
+++ b/src/SignerInfo.c
@@ -14,6 +14,34 @@
return true;
}
+
+HCOSE_SIGNER COSE_Signer_Init(CBOR_CONTEXT_COMMA cose_errback * perror)
+{
+ COSE_SignerInfo * pobj = (COSE_SignerInfo *)COSE_CALLOC(1, sizeof(COSE_SignerInfo), context);
+ if (pobj == NULL) {
+ if (perror != NULL) perror->err = COSE_ERR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ if (!_COSE_Init(&pobj->m_message, COSE_recipient_object, CBOR_CONTEXT_PARAM_COMMA perror)) {
+ COSE_Signer_Free((HCOSE_SIGNER)pobj);
+ return NULL;
+ }
+
+ return (HCOSE_SIGNER)pobj;
+}
+
+bool COSE_Signer_Free(HCOSE_SIGNER hSigner)
+{
+ if (IsValidSignerHandle(hSigner)) {
+
+ _COSE_Signer_Free((COSE_SignerInfo *)hSigner);
+ return true;
+ }
+
+ return false;
+}
+
void _COSE_Signer_Free(COSE_SignerInfo * pSigner)
{
COSE_FREE(pSigner, &pSigner->m_message.m_allocContext);
@@ -74,16 +102,19 @@
cn_cbor * pcborBody2 = NULL;
cn_cbor * pcborProtected2 = NULL;
cn_cbor * pcborProtectedSign = NULL;
- cn_cbor * pcborProtectedSign2 = NULL;
cn_cbor * pArray = NULL;
+ cn_cbor * cn = NULL;
+ cn_cbor_errback cbor_error;
size_t cbToSign;
byte * pbToSign = NULL;
bool f;
+ int alg;
pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA NULL);
if (pArray == NULL) {
if (perr != NULL) perr->err = COSE_ERR_OUT_OF_MEMORY;
errorReturn:
+ if (cn != NULL) CN_CBOR_FREE(cn, context);
if (pcborBody2 != NULL) CN_CBOR_FREE(pcborBody2, context);
if (pcborProtected2 != NULL) CN_CBOR_FREE(pcborProtected2, context);
if (pArray != NULL) COSE_FREE(pArray, context);
@@ -91,22 +122,50 @@
return false;
}
+ cn = _COSE_map_get_int(&pSigner->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
+ if (cn == NULL) goto errorReturn;
+
+ if (cn->type == CN_CBOR_TEXT) {
+ FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
+ }
+ else {
+ CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
+
+ alg = (int)cn->v.uint;
+ }
+
+
+ pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(pArray != NULL, cbor_error);
+
+ cn = cn_cbor_string_create("Signature", CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
+ cn = NULL;
+
+ cn = cn_cbor_data_create(pcborProtected->v.bytes, (int) pcborProtected->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
+ cn = NULL;
+
pcborProtectedSign = _COSE_encode_protected(&pSigner->m_message, perr);
if (pcborProtectedSign == NULL) goto errorReturn;
- pcborBody2 = cn_cbor_data_create(pcborBody->v.bytes, (int) pcborBody->length, CBOR_CONTEXT_PARAM_COMMA NULL);
- CHECK_CONDITION(pcborBody2 != NULL, COSE_ERR_OUT_OF_MEMORY);
+ cn = cn_cbor_data_create(pcborProtectedSign->v.bytes, (int) pcborProtectedSign->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
+ cn = NULL;
- pcborProtected2 = cn_cbor_data_create(pcborProtected->v.bytes, (int) pcborProtected->length, CBOR_CONTEXT_PARAM_COMMA NULL);
- CHECK_CONDITION(pcborProtected2 != NULL, COSE_ERR_OUT_OF_MEMORY);
+ cn = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
+ cn = NULL;
- pcborProtectedSign2 = cn_cbor_data_create(pcborProtectedSign->v.bytes, (int) pcborProtectedSign->length, CBOR_CONTEXT_PARAM_COMMA NULL);
- CHECK_CONDITION(pcborProtectedSign2 != NULL, COSE_ERR_OUT_OF_MEMORY);
+ cn = cn_cbor_data_create(pcborBody->v.bytes, (int)pcborBody->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
+ cn = NULL;
- CHECK_CONDITION(cn_cbor_array_append(pArray, pcborProtected2, NULL), COSE_ERR_CBOR);
- CHECK_CONDITION(cn_cbor_array_append(pArray, pcborProtectedSign2, NULL), COSE_ERR_CBOR);
- CHECK_CONDITION(cn_cbor_array_append(pArray, cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA NULL), NULL), COSE_ERR_CBOR);
- CHECK_CONDITION(cn_cbor_array_append(pArray, pcborBody2, NULL), COSE_ERR_CBOR);
cbToSign = cn_cbor_encoder_write(RgbDontUse4, 0, sizeof(RgbDontUse4), pArray);
CHECK_CONDITION(cbToSign > 0, COSE_ERR_CBOR);
@@ -114,7 +173,22 @@
CHECK_CONDITION(pbToSign != NULL, COSE_ERR_OUT_OF_MEMORY);
CHECK_CONDITION(cn_cbor_encoder_write(pbToSign, 0, cbToSign, pArray), COSE_ERR_CBOR);
- f = ECDSA_Sign(pSigner, pbToSign, cbToSign, perr);
+ switch (alg) {
+ case COSE_Algorithm_ECDSA_SHA_256:
+ f = ECDSA_Sign(pSigner, 256, pbToSign, cbToSign, perr);
+ break;
+
+ case COSE_Algorithm_ECDSA_SHA_384:
+ f = ECDSA_Sign(pSigner, 384, pbToSign, cbToSign, perr);
+ break;
+
+ case COSE_Algorithm_ECDSA_SHA_512:
+ f = ECDSA_Sign(pSigner, 512, pbToSign, cbToSign, perr);
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+ }
COSE_FREE(pbToSign, context);
CN_CBOR_FREE(pArray, context);
@@ -248,3 +322,13 @@
return false;
}
+
+bool COSE_Signer_map_put(HCOSE_SIGNER h, int key, cn_cbor * value, int flags, cose_errback * perror)
+{
+ if (!IsValidSignerHandle(h) || (value == NULL)) {
+ if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
+ return false;
+ }
+
+ return _COSE_map_put(&((COSE_SignerInfo *)h)->m_message, key, value, flags, perror);
+}
diff --git a/src/cose.h b/src/cose.h
index 907f1c8..609c4c6 100644
--- a/src/cose.h
+++ b/src/cose.h
@@ -187,7 +187,15 @@
bool COSE_Sign_SetContent(HCOSE_SIGN cose, const byte * rgbContent, size_t cbContent, cose_errback * errp);
HCOSE_SIGNER COSE_Sign_add_signer(HCOSE_SIGN cose, const cn_cbor * pkey, int algId, cose_errback * perr);
+extern bool COSE_Sign_AddSigner(HCOSE_SIGN hSign, HCOSE_SIGNER hSigner, cose_errback * perr);
bool COSE_Sign_Sign(HCOSE_SIGN h, cose_errback * perr);
HCOSE_SIGNER COSE_Sign_GetSigner(HCOSE_SIGN cose, int iSigner, cose_errback * perr);
bool COSE_Sign_validate(HCOSE_SIGN hSign, HCOSE_SIGNER hSigner, cose_errback * perr);
+cn_cbor * COSE_Sign_map_get_int(HCOSE_SIGN h, int key, int flags, cose_errback * perror);
+bool COSE_Sign_map_put(HCOSE_SIGN cose, int key, cn_cbor * value, int flags, cose_errback * errp);
+
+
+HCOSE_SIGNER COSE_Signer_Init(CBOR_CONTEXT_COMMA cose_errback * perror);
+bool COSE_Signer_Free(HCOSE_SIGNER cose);
bool COSE_Signer_SetKey(HCOSE_SIGNER hSigner, const cn_cbor * pkey, cose_errback * perr);
+bool COSE_Signer_map_put(HCOSE_SIGNER cose, int key, cn_cbor * value, int flags, cose_errback * errp);
diff --git a/src/cose_int.h b/src/cose_int.h
index 1ca34fe..b993449 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -165,7 +165,7 @@
#define INDEX_PROTECTED 0
#define INDEX_UNPROTECTED 1
#define INDEX_BODY 2
-#define INDEX_SIGNATURES 3
+#define INDEX_SIGNERS 3
#define INDEX_RECIPIENTS 3
#define INDEX_MAC_TAG 3
#define INDEX_MAC_RECIPIENTS 4
diff --git a/src/crypto.h b/src/crypto.h
index 52f84f1..5eb16d9 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -55,7 +55,7 @@
* @param[in] cose_errback * Error return location
* @return Did the function succeed?
*/
-bool ECDSA_Sign(COSE_SignerInfo * pSigner, const byte * rgbToSign, size_t cbToSign, cose_errback * perr);
+bool ECDSA_Sign(COSE_SignerInfo * pSigner, int cbitsDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr);
bool ECDSA_Verify(COSE_SignerInfo * pSigner, int cbitsDigest, const byte * rgbToSign, size_t cbToSign, const byte * rgbSig, size_t cbSig, cose_errback * perr);
/**
diff --git a/src/openssl.c b/src/openssl.c
index 560d766..214214d 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -625,7 +625,7 @@
#define COSE_Key_EC_Y -3
#define COSE_Key_EC_d -4
-EC_KEY * ECKey_From(const cn_cbor * pKey, cose_errback * perr)
+EC_KEY * ECKey_From(const cn_cbor * pKey, int * cbGroup, cose_errback * perr)
{
EC_KEY * pNewKey = EC_KEY_new();
byte rgbKey[512+1];
@@ -639,14 +639,17 @@
switch (p->v.sint) {
case 1: // P-256
nidGroup = NID_X9_62_prime256v1;
+ *cbGroup = 256 / 8;
break;
case 2: // P-384
nidGroup = NID_secp384r1;
+ *cbGroup = 384 / 8;
break;
case 3: // P-521
nidGroup = NID_secp521r1;
+ *cbGroup = (521 + 7) / 8;
break;
default:
@@ -700,19 +703,25 @@
}
*/
-bool ECDSA_Sign(COSE_SignerInfo * pSigner, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
+bool ECDSA_Sign(COSE_SignerInfo * pSigner, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
{
EC_KEY * eckey = NULL;
byte rgbDigest[EVP_MAX_MD_SIZE];
unsigned int cbDigest = sizeof(rgbDigest);
byte * pbSig = NULL;
unsigned int cbSig;
+ const EVP_MD * digest;
#ifdef USE_CBOR_CONTEXT
cn_cbor_context * context = &pSigner->m_message.m_allocContext;
#endif
cn_cbor * p = NULL;
+ ECDSA_SIG * psig = NULL;
+ cn_cbor_errback cbor_error;
+ int cbR;
+ byte rgbSig[66];
+ int cb;
- eckey = ECKey_From(pSigner->m_pkey, perr);
+ eckey = ECKey_From(pSigner->m_pkey, &cbR, perr);
if (eckey == NULL) {
errorReturn:
if (p != NULL) CN_CBOR_FREE(p, context);
@@ -720,16 +729,34 @@
return false;
}
- EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, EVP_sha256(), NULL);
+ switch (cbitDigest) {
+ case 256: digest = EVP_sha256(); break;
+ case 512: digest = EVP_sha512(); break;
+ case 384: digest = EVP_sha384(); break;
+ default:
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+ }
- cbSig = ECDSA_size(eckey);
- pbSig = COSE_CALLOC(cbSig, 1, context);
+ EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, NULL);
+
+ psig = ECDSA_do_sign(rgbDigest, cbDigest, eckey);
+ CHECK_CONDITION(psig != NULL, COSE_ERR_CRYPTO_FAIL);
+
+ pbSig = COSE_CALLOC(cbR, 2, context);
CHECK_CONDITION(pbSig != NULL, COSE_ERR_OUT_OF_MEMORY);
- CHECK_CONDITION(ECDSA_sign(0, rgbDigest, cbDigest, pbSig, &cbSig, eckey), COSE_ERR_CRYPTO_FAIL);
- p = cn_cbor_data_create(pbSig, cbSig, CBOR_CONTEXT_PARAM_COMMA NULL);
- CHECK_CONDITION(p != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ cb = BN_bn2bin(psig->r, rgbSig);
+ CHECK_CONDITION(cb <= cbR, COSE_ERR_INVALID_PARAMETER);
+ memcpy(pbSig + cbR - cb, rgbSig, cb);
+
+ cb = BN_bn2bin(psig->s, rgbSig);
+ CHECK_CONDITION(cb <= cbR, COSE_ERR_INVALID_PARAMETER);
+ memcpy(pbSig + 2*cbR - cb, rgbSig, cb);
+
+ p = cn_cbor_data_create(pbSig, cbR*2, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(p != NULL, cbor_error);
CHECK_CONDITION(_COSE_array_replace(&pSigner->m_message, p, INDEX_SIGNATURE, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
@@ -747,8 +774,9 @@
#endif
cn_cbor * p = NULL;
ECDSA_SIG sig = { NULL, NULL };
+ int cbR;
- eckey = ECKey_From(pSigner->m_pkey, perr);
+ eckey = ECKey_From(pSigner->m_pkey, &cbR, perr);
if (eckey == NULL) {
errorReturn:
if (sig.r != NULL) BN_free(sig.r);
@@ -767,6 +795,7 @@
}
EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, NULL);
+ CHECK_CONDITION(cbSignature / 2 == cbR, COSE_ERR_INVALID_PARAMETER);
sig.r = BN_bin2bn(rgbSignature,(int) cbSignature/2, NULL);
sig.s = BN_bin2bn(rgbSignature+cbSignature/2, (int) cbSignature/2, NULL);
diff --git a/test/sign.c b/test/sign.c
index ab0507c..cb12920 100644
--- a/test/sign.c
+++ b/test/sign.c
@@ -12,7 +12,7 @@
#include "test.h"
#include "context.h"
-int _ValidateSigned(const cn_cbor * pControl, const byte * pbEncoded, int cbEncoded)
+int _ValidateSigned(const cn_cbor * pControl, const byte * pbEncoded, size_t cbEncoded)
{
const cn_cbor * pInput = cn_cbor_mapget_string(pControl, "input");
const cn_cbor * pFail;
@@ -40,7 +40,7 @@
pSigners = cn_cbor_mapget_string(pSign, "signers");
if ((pSigners == NULL) || (pSigners->type != CN_CBOR_ARRAY)) exit(1);
- iSigner = pSigners->length - 1;
+ iSigner = (int) pSigners->length - 1;
pSigners = pSigners->first_child;
for (; pSigners != NULL; iSigner--, pSigners = pSigners->next) {
@@ -98,6 +98,69 @@
return _ValidateSigned(pControl, pbEncoded, cbEncoded);
}
+int BuildSignedMessage(const cn_cbor * pControl)
+{
+ int iSigner;
+
+ //
+ // We don't run this for all control sequences - skip those marked fail.
+ //
+
+ const cn_cbor * pFail = cn_cbor_mapget_string(pControl, "fail");
+ if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) return 0;
+
+ HCOSE_SIGN hSignObj = COSE_Sign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+
+ const cn_cbor * pInputs = cn_cbor_mapget_string(pControl, "input");
+ if (pInputs == NULL) exit(1);
+ const cn_cbor * pSign = cn_cbor_mapget_string(pInputs, "sign");
+ if (pSign == NULL) exit(1);
+
+ const cn_cbor * pContent = cn_cbor_mapget_string(pInputs, "plaintext");
+ if (!COSE_Sign_SetContent(hSignObj, pContent->v.bytes, pContent->length, NULL)) goto returnError;
+
+ if (!SetAttributes((HCOSE)hSignObj, cn_cbor_mapget_string(pSign, "protected"), Attributes_Sign_protected)) goto returnError;
+ if (!SetAttributes((HCOSE)hSignObj, cn_cbor_mapget_string(pSign, "unprotected"), Attributes_Sign_unprotected)) goto returnError;
+ if (!SetAttributes((HCOSE)hSignObj, cn_cbor_mapget_string(pSign, "unsent"), Attributes_Sign_unsent)) goto returnError;
+
+ const cn_cbor * pAlg = COSE_Sign_map_get_int(hSignObj, 1, COSE_BOTH, NULL);
+
+ const cn_cbor * pSigners = cn_cbor_mapget_string(pSign, "signers");
+ if ((pSigners == NULL) || (pSigners->type != CN_CBOR_ARRAY)) exit(1);
+
+ pSigners = pSigners->first_child;
+ for (iSigner = 0; pSigners != NULL; iSigner++, pSigners = pSigners->next) {
+ cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pSigners, "key"));
+ if (pkey == NULL) exit(1);
+
+ HCOSE_SIGNER hSigner = COSE_Signer_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+ if (hSigner == NULL) exit(1);
+
+ if (!SetAttributes((HCOSE)hSigner, cn_cbor_mapget_string(pSigners, "protected"), Attributes_Signer_protected)) goto returnError;
+ if (!SetAttributes((HCOSE)hSigner, cn_cbor_mapget_string(pSigners, "unprotected"), Attributes_Signer_unprotected)) goto returnError;
+ if (!SetAttributes((HCOSE)hSigner, cn_cbor_mapget_string(pSigners, "unsent"), Attributes_Signer_unsent)) goto returnError;
+
+ if (!COSE_Signer_SetKey(hSigner, pkey, NULL)) exit(1);
+
+ if (!COSE_Sign_AddSigner(hSignObj, hSigner, NULL)) exit(1);
+ }
+
+ if (!COSE_Sign_Sign(hSignObj, NULL)) exit(1);
+
+ size_t cb = COSE_Encode((HCOSE)hSignObj, NULL, 0, 0) + 1;
+ byte * rgb = (byte *)malloc(cb);
+ cb = COSE_Encode((HCOSE)hSignObj, rgb, 0, cb);
+
+ int f = _ValidateSigned(pControl, rgb, cb);
+
+ free(rgb);
+ return f;
+
+returnError:
+ CFails += 1;
+ return 1;
+}
+
int SignMessage()
{
diff --git a/test/test.c b/test/test.c
index c86ffc4..2d56925 100644
--- a/test/test.c
+++ b/test/test.c
@@ -25,7 +25,7 @@
int i;
} NameMap;
-NameMap RgAlgorithmNames[23] = {
+NameMap RgAlgorithmNames[26] = {
{"HS256", COSE_Algorithm_HMAC_256_256},
{"HS256/64", COSE_Algorithm_HMAC_256_64},
{"HS384", COSE_Algorithm_HMAC_384_384},
@@ -48,7 +48,10 @@
{"AES-CCM-64-128/64", COSE_Algorithm_AES_CCM_64_64_128},
{"AES-CCM-64-256/64", COSE_Algorithm_AES_CCM_64_64_256},
{"AES-CCM-64-128/128", COSE_Algorithm_AES_CCM_64_128_128},
- {"AES-CCM-64-256/128", COSE_Algorithm_AES_CCM_64_128_256}
+ {"AES-CCM-64-256/128", COSE_Algorithm_AES_CCM_64_128_256},
+ {"ES256", COSE_Algorithm_ECDSA_SHA_256},
+ {"ES384", COSE_Algorithm_ECDSA_SHA_384},
+ {"ES512", COSE_Algorithm_ECDSA_SHA_512},
};
@@ -209,6 +212,30 @@
case Attributes_Enveloped_unsent:
COSE_Encrypt_map_put((HCOSE_ENCRYPT)hHandle, keyNew, pValueNew, COSE_DONT_SEND, NULL);
break;
+
+ case Attributes_Sign_protected:
+ COSE_Sign_map_put((HCOSE_SIGN)hHandle, keyNew, pValueNew, COSE_PROTECT_ONLY, NULL);
+ break;
+
+ case Attributes_Sign_unprotected:
+ COSE_Sign_map_put((HCOSE_SIGN)hHandle, keyNew, pValueNew, COSE_UNPROTECT_ONLY, NULL);
+ break;
+
+ case Attributes_Sign_unsent:
+ COSE_Sign_map_put((HCOSE_SIGN)hHandle, keyNew, pValueNew, COSE_DONT_SEND, NULL);
+ break;
+
+ case Attributes_Signer_protected:
+ COSE_Signer_map_put((HCOSE_SIGNER)hHandle, keyNew, pValueNew, COSE_PROTECT_ONLY, NULL);
+ break;
+
+ case Attributes_Signer_unprotected:
+ COSE_Signer_map_put((HCOSE_SIGNER)hHandle, keyNew, pValueNew, COSE_UNPROTECT_ONLY, NULL);
+ break;
+
+ case Attributes_Signer_unsent:
+ COSE_Signer_map_put((HCOSE_SIGNER)hHandle, keyNew, pValueNew, COSE_DONT_SEND, NULL);
+ break;
}
}
@@ -537,6 +564,7 @@
}
else if (cn_cbor_mapget_string(pInput, "sign") != NULL) {
ValidateSigned(pControl);
+ BuildSignedMessage(pControl);
}
}
else {
diff --git a/test/test.h b/test/test.h
index 5150c75..0a4ecd4 100644
--- a/test/test.h
+++ b/test/test.h
@@ -34,6 +34,12 @@
Attributes_Enveloped_protected,
Attributes_Enveloped_unprotected,
Attributes_Enveloped_unsent,
+ Attributes_Sign_protected,
+ Attributes_Sign_unprotected,
+ Attributes_Sign_unsent,
+ Attributes_Signer_protected,
+ Attributes_Signer_unprotected,
+ Attributes_Signer_unsent,
} whichSet;
extern int CFails;