/** * Verify a signed interest * * params are as returned in upcall info structure * key is what should be used to verify * * returns: * -1 for parsing error * 0 for incorrect signature / unverified * 1 for proper verification * */ int verify_signed_interest(const unsigned char *ccnb, const struct ccn_indexbuf *comps, size_t num_comps, size_t start, size_t stop, struct ccn_pkey* key) { fprintf(stderr,"verifying signed interest...\n"); // What is info->interest_comps->n ? //fprintf(stderr, "Interest components %d\n", (int) info->interest_comps->n); unsigned char* comp; size_t size; int res; // Create a charbuf with the matched interest name incl nonce struct ccn_charbuf* name = ccn_charbuf_create(); ccn_name_init(name); res = ccn_name_append_components(name, ccnb, start, stop); // Last component, should be the signature res = ccn_name_comp_get(ccnb, comps, num_comps, (const unsigned char**)&comp, &size); if (memcmp(NS_SIGNATURE, comp, NS_SIGNATURE_LEN) != 0) { fprintf(stderr, "debug: Last component not tagged as a signature.\n"); return(-1); } // Parse our nameless, dataless content object that follows the namespace // and replace the name with the implicit name from the interest, so that // we can use the standard signature verification calls. Could be made // more efficient with different library calls. struct ccn_charbuf* co_with_name = ccn_charbuf_create(); unsigned char* co = &comp[NS_SIGNATURE_LEN]; replace_name(co_with_name, co, size-NS_SIGNATURE_LEN, name); //fprintf(stderr, "replace_name == %d (%s)\n", res, (res==0)?"ok":"fail"); // For now, use standard routines to verify signature struct ccn_parsed_ContentObject pco = {0}; fprintf(stderr,"verifying signed interest...2\n"); res = ccn_parse_ContentObject(co_with_name->buf, co_with_name->length, &pco, NULL); if (!res) { // Verify the signature against the authorized public key given to us, passed through to the handler res = ccn_verify_signature(co_with_name->buf, pco.offset[CCN_PCO_E], &pco, key ); } else { fprintf(stderr, "debug: Constructed content object parse failed (res==%d)\n", res); } fprintf(stderr,"verifying signed interest...3\n"); ccn_charbuf_destroy(&co_with_name); ccn_charbuf_destroy(&name); return (res); }
int decode_message(struct ccn_charbuf *message, struct path * name_path, char *data, size_t len, const void *verkey) { struct ccn_parsed_ContentObject content; struct ccn_indexbuf *comps = ccn_indexbuf_create(); const unsigned char * content_value; size_t content_length; int res = 0; int i; memset(&content, 0x33, sizeof(content)); if (ccn_parse_ContentObject(message->buf, message->length, &content, comps) != 0) { printf("Decode failed to parse object\n"); res = -1; } if (comps->n-1 != name_path->count) { printf("Decode got wrong number of path components: %d vs. %d\n", (int)(comps->n-1), name_path->count); res = -1; } for (i=0; i<name_path->count; i++) { if (ccn_name_comp_strcmp(message->buf, comps, i, name_path->comps[i]) != 0) { printf("Decode mismatch on path component %d\n", i); res = -1; } } if (ccn_content_get_value(message->buf, message->length, &content, &content_value, &content_length) != 0) { printf("Cannot retrieve content value\n"); res = -1; } else if (content_length != len) { printf("Decode mismatch on content length %d vs. %d\n", (int)content_length, (int)len); res = -1; } else if (memcmp(content_value, data, len) != 0) { printf("Decode mismatch of content\n"); res = -1; } if (ccn_verify_signature(message->buf, message->length, &content, verkey) != 1) { printf("Signature did not verify\n"); res = -1; } ccn_indexbuf_destroy(&comps); return res; }
PyObject * _pyccn_cmd_verify_signature(PyObject *UNUSED(self), PyObject *args) { PyObject *py_content_object, *py_pub_key; PyObject *res; struct ccn_charbuf *content_object; struct ccn_parsed_ContentObject *pco; struct ccn_pkey *pub_key; int r; if (!PyArg_ParseTuple(args, "OO", &py_content_object, &py_pub_key)) return NULL; if (!CCNObject_IsValid(CONTENT_OBJECT, py_content_object)) { PyErr_SetString(PyExc_TypeError, "argument 1 must be CCN" " ContentObject"); return NULL; } if (!CCNObject_IsValid(PKEY_PUB, py_pub_key)) { PyErr_SetString(PyExc_TypeError, "argument 2 must be CCN public key"); return NULL; } content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object); pco = _pyccn_content_object_get_pco(py_content_object); if (!pco) return NULL; pub_key = CCNObject_Get(PKEY_PUB, py_pub_key); r = ccn_verify_signature(content_object->buf, content_object->length, pco, pub_key); if (r < 0) { PyErr_SetString(g_PyExc_CCNSignatureError, "error verifying signature"); return NULL; } res = r ? Py_True : Py_False; return Py_INCREF(res), res; }
void ParsedContentObject::verifySignature(const CertPtr &cert) { m_verified = (ccn_verify_signature(head(m_bytes), m_pco.offset[CCN_PCO_E], &m_pco, cert->pkey()) == 1); }