Exemplo n.º 1
0
/*
 * deliver_content is used to deliver a previously-buffered
 * ContentObject to the client.
 */
static enum ccn_upcall_res
deliver_content(struct ccn *h, struct bulkdata *b)
{
    struct ccn_upcall_info info = {0};
    struct ccn_parsed_ContentObject obj = {0};
    struct pending *p = b->first;
    int res;
    enum ccn_upcall_res ans;
    assert(p != NULL && p->x == b->next_expected && p->content_ccnb != NULL);
    info.pco = &obj;
    info.content_comps = ccn_indexbuf_create();
    res = ccn_parse_ContentObject(p->content_ccnb, p->content_size,
                                  &obj, info.content_comps);
    assert(res >= 0);
    info.content_ccnb = p->content_ccnb;
    info.matched_comps = info.content_comps->n - 2;
    /* XXX - we have no matched interest to present */
    ans = (*b->client->p)(b->client, CCN_UPCALL_CONTENT, &info);
    // XXX - check for refusal
    info.content_ccnb = NULL;
    free(p->content_ccnb);
    p->content_ccnb = NULL;
    p->content_size = 0;
    ccn_indexbuf_destroy(&info.content_comps);
    if (ans == CCN_UPCALL_RESULT_OK) {
        struct ccn_closure *old = &p->closure;
        if ((--(old->refcount)) == 0) {
            info.pco = NULL;
            (old->p)(old, CCN_UPCALL_FINAL, &info);
        }
    }
    return(ans);
}
Exemplo n.º 2
0
/**
 * Parses content object and sets content->flatname
 */
static int
r_store_set_flatname(struct ccnr_handle *h, struct content_entry *content,
                     struct ccn_parsed_ContentObject *pco)
{
    int res;
    struct ccn_charbuf *flatname = NULL;
    const unsigned char *msg = NULL;
    size_t size;
    
    msg = r_store_content_base(h, content);
    size = content->size;
    if (msg == NULL)
        goto Bail;
    flatname = ccn_charbuf_create();
    if (flatname == NULL)
        goto Bail;    
    res = ccn_parse_ContentObject(msg, size, pco, NULL);
    if (res < 0) {
        ccnr_msg(h, "error parsing ContentObject - code %d", res);
        goto Bail;
    }
    ccn_digest_ContentObject(msg, pco);
    if (pco->digest_bytes != 32)
        goto Bail;
    res = ccn_flatname_from_ccnb(flatname, msg, size);
    if (res < 0) goto Bail;
    res = ccn_flatname_append_component(flatname, pco->digest, pco->digest_bytes);
    if (res < 0) goto Bail;
    content->flatname = flatname;
    flatname = NULL;
    return(0);
Bail:
    ccn_charbuf_destroy(&flatname);
    return(-1);
}
Exemplo n.º 3
0
/**
 * 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);

}
Exemplo n.º 4
0
void
ParsedContentObject::init(const unsigned char *data, size_t len)
{
  readRaw(m_bytes, data, len);

  m_comps = ccn_indexbuf_create();
  int res = ccn_parse_ContentObject(head (m_bytes), len, &m_pco, m_comps);
  if (res < 0)
  {
    boost::throw_exception(MisformedContentObjectException());
  }

}
Exemplo n.º 5
0
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;

}
Exemplo n.º 6
0
// replace_name()
// Helper function to replace names in content objects
// Could build another version that works on already parsed content objects
// But as seen below it would be better to use a modified encoding call that
// didn't include the name at all.
//
int replace_name(struct ccn_charbuf* dest, unsigned char* src,  size_t src_size, struct ccn_charbuf* name) {
	struct ccn_parsed_ContentObject* pco = (struct ccn_parsed_ContentObject*) calloc(sizeof(struct ccn_parsed_ContentObject), 1);
	int res = 0;
	res = ccn_parse_ContentObject(src,src_size, pco, NULL);
    if (res < 0) {
    	free(pco);
    	return (res);
    }
	ccn_charbuf_append_tt(dest, CCN_DTAG_ContentObject, CCN_DTAG);
	ccn_charbuf_append(dest, &src[pco->offset[CCN_PCO_B_Signature]], pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature]);
	ccn_charbuf_append_charbuf(dest, name); // Already tagged
	ccn_charbuf_append(dest, &src[pco->offset[CCN_PCO_B_SignedInfo]], pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo]);
	ccnb_append_tagged_blob(dest, CCN_DTAG_Content, NULL, 0);
	ccn_charbuf_append_closer(dest);
	free(pco);
	return (0);
}
Exemplo n.º 7
0
static int
parse_ContentObject(PyObject *py_content_object)
{
    struct content_object_data *context;
    struct ccn_charbuf *content_object;
    int r;

    assert(CCNObject_IsValid(CONTENT_OBJECT, py_content_object));

    context = PyCapsule_GetContext(py_content_object);
    assert(context);
    if (context->pco)
        free(context->pco);
    ccn_indexbuf_destroy(&context->comps);

    /*
     * no error happens between deallocation and following line, so I'm not
     * setting context->pco to NULL
     */
    context->pco = calloc(1, sizeof(struct ccn_parsed_ContentObject));
    JUMP_IF_NULL_MEM(context->pco, error);

    context->comps = ccn_indexbuf_create();
    JUMP_IF_NULL_MEM(context->comps, error);

    content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object);

    r = ccn_parse_ContentObject(content_object->buf, content_object->length,
                                context->pco, context->comps);
    if (r < 0) {
        PyErr_SetString(g_PyExc_CCNContentObjectError, "Unable to parse the"
                        " ContentObject");
        goto error;
    }

    return 0;
error:
    if (context->pco) {
        free(context->pco);
        context->pco = NULL;
    }
    ccn_indexbuf_destroy(&context->comps);
    return -1;
}
Exemplo n.º 8
0
PUBLIC int
r_store_content_field_access(struct ccnr_handle *h,
                             struct content_entry *content,
                             enum ccn_dtag dtag,
                             const unsigned char **bufp, size_t *sizep)
{
    int res = -1;
    const unsigned char *content_msg;
    struct ccn_parsed_ContentObject pco = {0};
    
    content_msg = r_store_content_base(h, content);
    if (content_msg == NULL)
        return(-1);
    res = ccn_parse_ContentObject(content_msg, content->size, &pco, NULL);
    if (res < 0)
        return(-1);
    if (dtag == CCN_DTAG_Content)
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, content_msg,
                                  pco.offset[CCN_PCO_B_Content],
                                  pco.offset[CCN_PCO_E_Content],
                                  bufp, sizep);
    return(res);
}
Exemplo n.º 9
0
static int
dissect_ccn_contentobject(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *signature_tree;
    proto_tree *name_tree;
    proto_tree *signedinfo_tree;
    proto_tree *content_tree;
    proto_item *titem;
    struct ccn_parsed_ContentObject co;
    struct ccn_parsed_ContentObject *pco = &co;
    struct ccn_charbuf *c;
    struct ccn_indexbuf *comps;
    const unsigned char *comp;
    size_t comp_size;
    size_t blob_size;
    const unsigned char *blob;
    int l;
    unsigned int i;
    double dt;
    nstime_t timestamp;
    int res;

    comps = ccn_indexbuf_create();
    res = ccn_parse_ContentObject(ccnb, ccnb_size, pco, comps);
    if (res < 0) return (-1);

    /* Signature */
    l = pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature];
    titem = proto_tree_add_item(tree, hf_ccn_signature, tvb, pco->offset[CCN_PCO_B_Signature], l, FALSE);
    signature_tree = proto_item_add_subtree(titem, ett_signature);

    /* DigestAlgorithm */
    l = pco->offset[CCN_PCO_E_DigestAlgorithm] - pco->offset[CCN_PCO_B_DigestAlgorithm];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, ccnb,
                                  pco->offset[CCN_PCO_B_DigestAlgorithm],
                                  pco->offset[CCN_PCO_E_DigestAlgorithm],
                                  &blob, &blob_size);
        titem = proto_tree_add_item(signature_tree, hf_ccn_signaturedigestalg, tvb,
                                    blob - ccnb, blob_size, FALSE);
    }
    /* Witness */
    l = pco->offset[CCN_PCO_E_Witness] - pco->offset[CCN_PCO_B_Witness];
    if (l > 0) {
        /* add the witness item to the signature tree */
    }

    /* Signature bits */
    l = pco->offset[CCN_PCO_E_SignatureBits] - pco->offset[CCN_PCO_B_SignatureBits];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, ccnb,
                                  pco->offset[CCN_PCO_B_SignatureBits],
                                  pco->offset[CCN_PCO_E_SignatureBits],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signature_tree, hf_ccn_signaturebits, tvb,
                                     blob - ccnb, blob_size, blob);
    }

    /* /Signature */

    /* Name */
    l = pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name];
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    titem = proto_tree_add_string(tree, hf_ccn_name, tvb,
                                      pco->offset[CCN_PCO_B_Name], l,
                                      ccn_charbuf_as_string(c));
    name_tree = proto_item_add_subtree(titem, ett_name);
    ccn_charbuf_destroy(&c);

    /* Name Components */
    for (i = 0; i < comps->n - 1; i++) {
        res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size);
        titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE);
    }

    /* /Name */

    /* SignedInfo */
    l = pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo];
    titem = proto_tree_add_text(tree, tvb,
                                         pco->offset[CCN_PCO_B_SignedInfo], l,
                                         "SignedInfo");
    signedinfo_tree = proto_item_add_subtree(titem, ett_signedinfo);

    /* PublisherPublicKeyDigest */
    l = pco->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pco->offset[CCN_PCO_B_PublisherPublicKeyDigest];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, ccnb,
                                  pco->offset[CCN_PCO_B_PublisherPublicKeyDigest],
                                  pco->offset[CCN_PCO_E_PublisherPublicKeyDigest],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signedinfo_tree, hf_ccn_publisherpublickeydigest, tvb, blob - ccnb, blob_size, blob);
    }

    /* Timestamp */
    l = pco->offset[CCN_PCO_E_Timestamp] - pco->offset[CCN_PCO_B_Timestamp];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, ccnb,
                                  pco->offset[CCN_PCO_B_Timestamp],
                                  pco->offset[CCN_PCO_E_Timestamp],
                                  &blob, &blob_size);
        dt = 0.0;
        for (i = 0; i < blob_size; i++)
            dt = dt * 256.0 + (double)blob[i];
        dt /= 4096.0;
        timestamp.secs = dt; /* truncates */
        timestamp.nsecs = (dt - (double) timestamp.secs) *  1000000000.0;
        titem = proto_tree_add_time(signedinfo_tree, hf_ccn_timestamp, tvb, blob - ccnb, blob_size, &timestamp);
    }

    /* Type */
    l = pco->offset[CCN_PCO_E_Type] - pco->offset[CCN_PCO_B_Type];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Type, ccnb,
                                  pco->offset[CCN_PCO_B_Type],
                                  pco->offset[CCN_PCO_E_Type],
                                  &blob, &blob_size);
        titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, tvb, blob - ccnb, blob_size, pco->type);
    } else {
        titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, NULL, 0, 0, pco->type);
    }

    /* FreshnessSeconds */
    l = pco->offset[CCN_PCO_E_FreshnessSeconds] - pco->offset[CCN_PCO_B_FreshnessSeconds];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FreshnessSeconds, ccnb,
                                  pco->offset[CCN_PCO_B_FreshnessSeconds],
                                  pco->offset[CCN_PCO_E_FreshnessSeconds],
                                  &blob, &blob_size);
        i = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_FreshnessSeconds, ccnb,
                                                  pco->offset[CCN_PCO_B_FreshnessSeconds],
                                                  pco->offset[CCN_PCO_E_FreshnessSeconds]);

        titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_freshnessseconds, tvb, blob - ccnb, blob_size, i);
    }

    /* FinalBlockID */
    l = pco->offset[CCN_PCO_E_FinalBlockID] - pco->offset[CCN_PCO_B_FinalBlockID];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb,
                                  pco->offset[CCN_PCO_B_FinalBlockID],
                                  pco->offset[CCN_PCO_E_FinalBlockID],
                                  &blob, &blob_size);

        titem = proto_tree_add_item(signedinfo_tree, hf_ccn_finalblockid, tvb, blob - ccnb, blob_size, FALSE);
    }
    /* TODO: KeyLocator */
    /* /SignedInfo */

    /* Content */
    l = pco->offset[CCN_PCO_E_Content] - pco->offset[CCN_PCO_B_Content];
    res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnb,
                                  pco->offset[CCN_PCO_B_Content],
                                  pco->offset[CCN_PCO_E_Content],
                                  &blob, &blob_size);
    titem = proto_tree_add_text(tree, tvb,
                                         pco->offset[CCN_PCO_B_Content], l,
                                         "Content: %d bytes", blob_size);
    if (blob_size > 0) {
        content_tree = proto_item_add_subtree(titem, ett_content);
        titem = proto_tree_add_item(content_tree, hf_ccn_contentdata, tvb, blob - ccnb, blob_size, FALSE);
    }

    return (ccnb_size);
}
Exemplo n.º 10
0
/**
 * Common interest handler
 */
PUBLIC enum ccn_upcall_res
ccnr_answer_req(struct ccn_closure *selfp,
                 enum ccn_upcall_kind kind,
                 struct ccn_upcall_info *info)
{
    struct ccn_charbuf *msg = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *keylocator = NULL;
    struct ccn_charbuf *signed_info = NULL;
    struct ccn_charbuf *reply_body = NULL;
    struct ccnr_handle *ccnr = NULL;
    int res = 0;
    int morecomps = 0;
    const unsigned char *final_comp = NULL;
    size_t final_size = 0;
    
    switch (kind) {
        case CCN_UPCALL_FINAL:
            free(selfp);
            return(CCN_UPCALL_RESULT_OK);
        case CCN_UPCALL_INTEREST:
            break;
        case CCN_UPCALL_CONSUMED_INTEREST:
            return(CCN_UPCALL_RESULT_OK);
        default:
            return(CCN_UPCALL_RESULT_ERR);
    }
    ccnr = (struct ccnr_handle *)selfp->data;
    if (CCNSHOULDLOG(ccnr, LM_128, CCNL_FINE))
        ccnr_debug_ccnb(ccnr, __LINE__, "ccnr_answer_req", NULL,
                        info->interest_ccnb, info->pi->offset[CCN_PI_E]);
    morecomps = selfp->intdata & MORECOMPS_MASK;
    if ((info->pi->answerfrom & CCN_AOK_NEW) == 0 &&
        selfp->intdata != OP_SERVICE)
        return(CCN_UPCALL_RESULT_OK);
    if (info->matched_comps >= info->interest_comps->n)
        goto Bail;
    if ((selfp->intdata & OPER_MASK) != OP_SERVICE &&
        info->pi->prefix_comps != info->matched_comps + morecomps)
        goto Bail;
    if (morecomps == 1) {
        res = ccn_name_comp_get(info->interest_ccnb, info->interest_comps,
                                info->matched_comps,
                                &final_comp, &final_size);
        if (res < 0)
            goto Bail;
    }
    if ((selfp->intdata & MUST_VERIFY) != 0) {
        struct ccn_parsed_ContentObject pco = {0};
        // XXX - probably should check for message origin BEFORE verify
        res = ccn_parse_ContentObject(final_comp, final_size, &pco, NULL);
        if (res < 0) {
            ccnr_debug_ccnb(ccnr, __LINE__, "co_parse_failed", NULL,
                            info->interest_ccnb, info->pi->offset[CCN_PI_E]);
            goto Bail;
        }
        res = ccn_verify_content(info->h, final_comp, &pco);
        if (res != 0) {
            ccnr_debug_ccnb(ccnr, __LINE__, "co_verify_failed", NULL,
                            info->interest_ccnb, info->pi->offset[CCN_PI_E]);
            goto Bail;
        }
    }
    switch (selfp->intdata & OPER_MASK) {
        case OP_SERVICE:
            if (ccnr->service_ccnb == NULL)
                ccnr->service_ccnb = ccnr_init_service_ccnb(ccnr, info->h, CCNRID_LOCAL_URI, 600);
            if (ccn_content_matches_interest(
                    ccnr->service_ccnb->buf,
                    ccnr->service_ccnb->length,
                    1,
                    NULL,
                    info->interest_ccnb,
                    info->pi->offset[CCN_PI_E],
                    info->pi
                )) {
                ccn_put(info->h, ccnr->service_ccnb->buf,
                                 ccnr->service_ccnb->length);
                res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
                goto Finish;
            }
            // XXX this needs refactoring.
            if (ccnr->neighbor_ccnb == NULL)
                ccnr->neighbor_ccnb = ccnr_init_service_ccnb(ccnr, info->h, CCNRID_NEIGHBOR_URI, 5);
            if (ccn_content_matches_interest(
                    ccnr->neighbor_ccnb->buf,
                    ccnr->neighbor_ccnb->length,
                    1,
                    NULL,
                    info->interest_ccnb,
                    info->pi->offset[CCN_PI_E],
                    info->pi
                )) {
                ccn_put(info->h, ccnr->neighbor_ccnb->buf,
                                 ccnr->neighbor_ccnb->length);
                res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
                goto Finish;
            }
            if (ccn_content_matches_interest(
                                             ccnr->policy_link_cob->buf,
                                             ccnr->policy_link_cob->length,
                                             1,
                                             NULL,
                                             info->interest_ccnb,
                                             info->pi->offset[CCN_PI_E],
                                             info->pi
                                             )) {
                ccn_put(info->h, ccnr->policy_link_cob->buf,
                        ccnr->policy_link_cob->length);
                res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
                goto Finish;
            }
            goto Bail;
            break;
        default:
            // No other OP_xxx are supported here
            goto Bail;
    }
Bail:
    res = CCN_UPCALL_RESULT_ERR;
Finish:
    ccn_charbuf_destroy(&msg);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&keylocator);
    ccn_charbuf_destroy(&reply_body);
    ccn_charbuf_destroy(&signed_info);
    return(res);
}
Exemplo n.º 11
0
int
main (int argc, char *argv[]) {
    struct ccn_charbuf *buffer = ccn_charbuf_create();
    struct ccn_charbuf *signed_info = ccn_charbuf_create();
    struct ccn_skeleton_decoder dd = {0};
    ssize_t res;
    char *outname = NULL;
    int fd;
    int result = 0;
    char * contents[] = {"INVITE sip:[email protected] SIP/2.0\nVia: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK519044721\nFrom: <sip:[email protected]>;tag=2105643453\nTo: Test User <sip:[email protected]>\nCall-ID: [email protected]\nCSeq: 20 INVITE\nContact: <sip:[email protected]:5060>\nMax-Forwards: 70\nUser-Agent: Linphone-1.7.1/eXosip\nSubject: Phone call\nExpires: 120\nAllow: INVITE, ACK, CANCEL, BYE, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE\nContent-Type: application/sdp\nContent-Length:   448\n\nv=0\no=jthornto 123456 654321 IN IP4 127.0.0.1\ns=A conversation\nc=IN IP4 127.0.0.1\nt=0 0\nm=audio 7078 RTP/AVP 111 110 0 3 8 101\na=rtpmap:111 speex/16000/1\na=rtpmap:110 speex/8000/1\na=rtpmap:0 PCMU/8000/1\na=rtpmap:3 GSM/8000/1\na=rtpmap:8 PCMA/8000/1\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-11\nm=video 9078 RTP/AVP 97 98 99\na=rtpmap:97 theora/90000\na=rtpmap:98 H263-1998/90000\na=fmtp:98 CIF=1;QCIF=1\na=rtpmap:99 MP4V-ES/90000\n", 
 
			 "Quaer #%2d zjduer  badone",
                         "",
                         NULL};
    char * paths[] = { "/sip/protocol/parc.com/domain/foo/principal/invite/verb/[email protected]/id", 
		       "/d/e/f",
                       "/zero/length/content",
                       NULL};
    struct path * cur_path = NULL;
    struct ccn_keystore *keystore = ccn_keystore_create();
    char *home = getenv("HOME");
    char *keystore_suffix = "/.ccnx/.ccnx_keystore";
    char *keystore_name = NULL;

    int i;

    if (argc == 3 && strcmp(argv[1], "-o") == 0) {
	outname = argv[2];
    } else {
	printf("Usage: %s -o <outfilename>\n", argv[0]);
	exit(1);
    }

    if (home == NULL) {
        printf("Unable to determine home directory for keystore\n");
        exit(1);
    }
    keystore_name = calloc(1, strlen(home) + strlen(keystore_suffix) + 1);
    
    strcat(keystore_name, home);
    strcat(keystore_name, keystore_suffix);

    if (0 != ccn_keystore_init(keystore, keystore_name, "Th1s1sn0t8g00dp8ssw0rd.")) {
        printf("Failed to initialize keystore\n");
        exit(1);
    }

    printf("Creating signed_info\n");
    res = ccn_signed_info_create(signed_info,
                                 /*pubkeyid*/ccn_keystore_public_key_digest(keystore),
                                 /*publisher_key_id_size*/ccn_keystore_public_key_digest_length(keystore),
                                 /*datetime*/NULL,
                                 /*type*/CCN_CONTENT_GONE,
                                 /*freshness*/ 42,
                                 /*finalblockid*/NULL,
                                 /*keylocator*/NULL);
    if (res < 0) {
        printf("Failed to create signed_info!\n");
    }
    
    res = ccn_skeleton_decode(&dd, signed_info->buf, signed_info->length);
    if (!(res == signed_info->length && dd.state == 0)) {
        printf("Failed to decode signed_info!  Result %d State %d\n", (int)res, dd.state);
        result = 1;
    }
    memset(&dd, 0, sizeof(dd));
    printf("Done with signed_info\n");

    printf("Encoding sample message data length %d\n", (int)strlen(contents[0]));
    cur_path = path_create(paths[0]);
    if (encode_message(buffer, cur_path, contents[0], strlen(contents[0]), signed_info, ccn_keystore_private_key(keystore))) {
	printf("Failed to encode message!\n");
    } else {
	printf("Encoded sample message length is %d\n", (int)buffer->length);

	res = ccn_skeleton_decode(&dd, buffer->buf, buffer->length);
	if (!(res == buffer->length && dd.state == 0)) {
	    printf("Failed to decode!  Result %d State %d\n", (int)res, dd.state);
	    result = 1;
	}
        if (outname != NULL) {
            fd = open(outname, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
            if (fd == -1)
                perror(outname);
            res = write(fd, buffer->buf, buffer->length);
            close(fd);
	}
        if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) != 0) {
	    result = 1;
	}
        printf("Expect signature verification failure: ");
        if (buffer->length >= 20)
            buffer->buf[buffer->length - 20] += 1;
	if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) == 0) {
	    result = 1;
	}
    }
    path_destroy(&cur_path);
    ccn_charbuf_destroy(&buffer);
    printf("Done with sample message\n");
    
    /* Now exercise as unit tests */
    
    for (i = 0; paths[i] != NULL && contents[i] != NULL; i++) {
	printf("Unit test case %d\n", i);
	cur_path = path_create(paths[i]);
	buffer = ccn_charbuf_create();
	if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_private_key(keystore))) {
	    printf("Failed encode\n");
            result = 1;
	} else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_public_key(keystore))) {
	    printf("Failed decode\n");
            result = 1;
	}
	path_destroy(&cur_path);
	ccn_charbuf_destroy(&buffer);
    }
    
    /* Test the uri encode / decode routines */
        
    init_all_chars_percent_encoded();
    const char *uri_tests[] = {
        "_+4", "ccnx:/this/is/a/test",       "",     "ccnx:/this/is/a/test",
        ".+4", "../test2?x=2",              "?x=2", "ccnx:/this/is/a/test2",
        "_-X", "../should/error",           "",     "",
        "_+2", "/missing/scheme",           "",     "ccnx:/missing/scheme",
        ".+0", "../../../../../././#/",     "#/",   "ccnx:/",
        ".+1", all_chars_percent_encoded,   "",     all_chars_percent_encoded_canon,
        "_+1", all_chars_percent_encoded_canon, "", all_chars_percent_encoded_canon,
        ".+4", "ccnx:/.../.%2e./...././.....///?...", "?...", "ccnx:/.../.../..../.....",
        "_-X", "/%3G?bad-pecent-encode",    "",     "",
        "_-X", "/%3?bad-percent-encode",    "",     "",
        "_-X", "/%#bad-percent-encode",    "",     "",
        "_+3", "ccnx://[email protected]:42/ignore/host/part of uri", "", "ccnx:/ignore/host/part%20of%20uri",
        NULL, NULL, NULL, NULL
    };
    const char **u;
    struct ccn_charbuf *uri_out = ccn_charbuf_create();
    buffer = ccn_charbuf_create();
    for (u = uri_tests; *u != NULL; u += 4, i++) {
        printf("Unit test case %d\n", i);
        if (u[0][0] != '.')
            buffer->length = 0;
        res = ccn_name_from_uri(buffer, u[1]);
        if (!expected_res(res, u[0][1])) {
            printf("Failed: ccn_name_from_uri wrong res %d\n", (int)res);
            result = 1;
        }
        if (res >= 0) {
            if (res > strlen(u[1])) {
                printf("Failed: ccn_name_from_uri long res %d\n", (int)res);
                result = 1;
            }
            else if (0 != strcmp(u[1] + res, u[2])) {
                printf("Failed: ccn_name_from_uri expecting leftover '%s', got '%s'\n", u[2], u[1] + res);
                result = 1;
            }
            uri_out->length = 0;
            res = ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
            if (!expected_res(res, u[0][2])) {
                printf("Failed: ccn_uri_append wrong res %d\n", (int)res);
                result = 1;
            }
            if (res >= 0) {
                if (uri_out->length != strlen(u[3])) {
                    printf("Failed: ccn_uri_append produced wrong number of characters\n");
                    result = 1;
                }
                ccn_charbuf_reserve(uri_out, 1)[0] = 0;
                if (0 != strcmp((const char *)uri_out->buf, u[3])) {
                    printf("Failed: ccn_uri_append produced wrong output\n");
                    printf("Expected: %s\n", u[3]);
                    printf("  Actual: %s\n", (const char *)uri_out->buf);
                    result = 1;
                }
            }
        }
    }
    ccn_charbuf_destroy(&buffer);
    ccn_charbuf_destroy(&uri_out);
    printf("Name marker tests\n");
    do {
        const char *expected_uri = "ccnx:/example.com/.../%01/%FE/%01%02%03%04%05%06%07%08/%FD%10%10%10%10%1F%FF/%00%81";
        const char *expected_chopped_uri = "ccnx:/example.com/.../%01/%FE";
        const char *expected_bumped_uri = "ccnx:/example.com/.../%01/%FF";
        const char *expected_bumped2_uri = "ccnx:/example.com/.../%01/%00%00";

        printf("Unit test case %d\n", i++);
        buffer = ccn_charbuf_create();
        uri_out = ccn_charbuf_create();
        res = ccn_name_init(buffer);
        res |= ccn_name_append_str(buffer, "example.com");
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0);
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1);
        res |= ccn_name_append_numeric(buffer, 0xFE, 0);
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL);
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL);
        res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129);
        res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
        if (res < 0) {
            printf("Failed: name marker tests had negative res\n");
            result = 1;
        }
        if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri)) {
            printf("Failed: name marker tests produced wrong output\n");
            printf("Expected: %s\n", expected_uri);
            printf("  Actual: %s\n", (const char *)uri_out->buf);
            result = 1;
        }
        res = ccn_name_chop(buffer, NULL, 100);
        if (res != -1) {
            printf("Failed: ccn_name_chop did not produce error \n");
            result = 1;
        }
        res = ccn_name_chop(buffer, NULL, 4);
        if (res != 4) {
            printf("Failed: ccn_name_chop got wrong length\n");
            result = 1;
        }
        uri_out->length = 0;
        ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
        if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_chopped_uri)) {
            printf("Failed: ccn_name_chop botch\n");
            printf("Expected: %s\n", expected_chopped_uri);
            printf("  Actual: %s\n", (const char *)uri_out->buf);
            result = 1;
        }
        res = ccn_name_next_sibling(buffer);
        if (res != 4) {
            printf("Failed: ccn_name_next_sibling got wrong length\n");
            result = 1;
        }
        uri_out->length = 0;
        ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
        if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped_uri)) {
            printf("Failed: ccn_name_next_sibling botch\n");
            printf("Expected: %s\n", expected_bumped_uri);
            printf("  Actual: %s\n", (const char *)uri_out->buf);
            result = 1;
        }
        ccn_name_next_sibling(buffer);
        uri_out->length = 0;
        ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
        if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped2_uri)) {
            printf("Failed: ccn_name_next_sibling botch\n");
            printf("Expected: %s\n", expected_bumped2_uri);
            printf("  Actual: %s\n", (const char *)uri_out->buf);
            result = 1;
        }
        ccn_charbuf_destroy(&buffer);
        ccn_charbuf_destroy(&uri_out);
    } while (0);
    printf("Message digest tests\n");
    do {
        printf("Unit test case %d\n", i++);
        struct ccn_digest *dg = ccn_digest_create(CCN_DIGEST_SHA256);
        if (dg == NULL) {
            printf("Failed: ccn_digest_create returned NULL\n");
            result = 1;
            break;
        }
        printf("Unit test case %d\n", i++);
        const unsigned char expected_digest[] = {
            0xb3, 0x82, 0xcd, 0xb0, 0xe9, 0x5d, 0xf7, 0x3b, 0xe7, 0xdc, 0x19, 0x81, 0x3a, 0xfd, 0xdf, 0x89, 0xfb, 0xd4, 0xd4, 0xa0, 0xdb, 0x11, 0xa6, 0xba, 0x24, 0x16, 0x5b, 0xad, 0x9d, 0x90, 0x72, 0xb0
        };
        unsigned char actual_digest[sizeof(expected_digest)] = {0};
        const char *data = "Content-centric";
        if (ccn_digest_size(dg) != sizeof(expected_digest)) {
            printf("Failed: wrong digest size\n");
            result = 1;
            break;
        }
        printf("Unit test case %d\n", i++);
        ccn_digest_init(dg);
        res = ccn_digest_update(dg, data, strlen(data));
        if (res != 0)
            printf("Warning: check res %d\n", (int)res);
        printf("Unit test case %d\n", i++);
        res = ccn_digest_final(dg, actual_digest, sizeof(expected_digest));
        if (res != 0)
            printf("Warning: check res %d\n", (int)res);
        if (0 != memcmp(actual_digest, expected_digest, sizeof(expected_digest))) {
            printf("Failed: wrong digest\n");
            result = 1;
            break;
        }
    } while (0);
    printf("Really basic PRNG test\n");
    do {
        unsigned char r1[42];
        unsigned char r2[42];
        printf("Unit test case %d\n", i++);
        ccn_add_entropy(&i, sizeof(i), 0); /* Not much entropy, really. */
        ccn_random_bytes(r1, sizeof(r1));
        memcpy(r2, r1, sizeof(r2));
        ccn_random_bytes(r2, sizeof(r2));
        if (0 == memcmp(r1, r2, sizeof(r2))) {
            printf("Failed: badly broken PRNG\n");
            result = 1;
            break;
        }
    } while (0);
    printf("Bloom filter tests\n");
    do {
        unsigned char seed1[4] = "1492";
        const char *a[13] = {
            "one", "two", "three", "four",
            "five", "six", "seven", "eight",
            "nine", "ten", "eleven", "twelve",
            "thirteen"
        };
        struct ccn_bloom *b1 = NULL;
        struct ccn_bloom *b2 = NULL;
        int j, k, t1, t2;
        unsigned short us;
        
        printf("Unit test case %d\n", i++);
        b1 = ccn_bloom_create(13, seed1);
        
        for (j = 0; j < 13; j++)
            if (ccn_bloom_match(b1, a[j], strlen(a[j]))) break;
        if (j < 13) {
            printf("Failed: \"%s\" matched empty Bloom filter\n", a[j]);
            result = 1;
            break;
        }
        printf("Unit test case %d\n", i++);
        for (j = 0; j < 13; j++)
            ccn_bloom_insert(b1, a[j], strlen(a[j]));
        for (j = 0; j < 13; j++)
            if (!ccn_bloom_match(b1, a[j], strlen(a[j]))) break;
        if (j < 13) {
            printf("Failed: \"%s\" not found when it should have been\n", a[j]);
            result = 1;
            break;
        }
        printf("Unit test case %d\n", i++);
        for (j = 0, k = 0; j < 13; j++)
            if (ccn_bloom_match(b1, a[j]+1, strlen(a[j]+1)))
                k++;
        if (k > 0) {
            printf("Mmm, found %d false positives\n", k);
            if (k > 2) {
                result = 1;
                break;
            }
        }
        unsigned char seed2[5] = "aqfb\0";
        for (; seed2[3] <= 'f'; seed2[3]++) {
            printf("Unit test case %d (%4s)    ", i++, seed2);
            b2 = ccn_bloom_create(13, seed2);
            for (j = 0; j < 13; j++)
                ccn_bloom_insert(b2, a[j], strlen(a[j]));
            for (j = 0, k = 0, us = ~0; us > 0; us--) {
                t1 = ccn_bloom_match(b1, &us, sizeof(us));
                t2 = ccn_bloom_match(b2, &us, sizeof(us));
                j += (t1 | t2);
                k += (t1 & t2);
            }
            printf("either=%d both=%d wiresize=%d\n", j, k, ccn_bloom_wiresize(b1));
            if (k > 12) {
                printf("Failed: Bloom seeding may not be effective\n");
                result = 1;
            }
            ccn_bloom_destroy(&b2);
        }
        ccn_bloom_destroy(&b1);
    } while (0);
    printf("ccn_sign_content() tests\n");
    do {
        struct ccn *h = ccn_create();
        struct ccn_charbuf *co = ccn_charbuf_create();
        struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT;
        struct ccn_parsed_ContentObject pco = {0};
        struct ccn_charbuf *name = ccn_charbuf_create();
        
        printf("Unit test case %d\n", i++);
        ccn_name_from_uri(name, "ccnx:/test/data/%00%42");
        res = ccn_sign_content(h, co, name, NULL, "DATA", 4);
        if (res != 0) {
            printf("Failed: res == %d\n", (int)res);
            result = 1;
        }
        sparm.template_ccnb = ccn_charbuf_create();
        res = ccn_parse_ContentObject(co->buf, co->length, &pco, NULL);
        if (res != 0) {
            printf("Failed: ccn_parse_ContentObject res == %d\n", (int)res);
            result = 1;
            break;
        }
        ccn_charbuf_append(sparm.template_ccnb,
            co->buf + pco.offset[CCN_PCO_B_SignedInfo],
            pco.offset[CCN_PCO_E_SignedInfo] - pco.offset[CCN_PCO_B_SignedInfo]);
        sparm.sp_flags = CCN_SP_TEMPL_TIMESTAMP;
        printf("Unit test case %d\n", i++);
        res = ccn_sign_content(h, co, name, &sparm, "DATA", 4);
        if (res != 0) {
            printf("Failed: res == %d\n", (int)res);
            result = 1;
        }
        printf("Unit test case %d\n", i++);
        sparm.sp_flags = -1;
        res = ccn_sign_content(h, co, name, &sparm, "DATA", 4);
        if (res != -1) {
            printf("Failed: res == %d\n", (int)res);
            result = 1;
        }
        ccn_charbuf_destroy(&name);
        ccn_charbuf_destroy(&sparm.template_ccnb);
        ccn_charbuf_destroy(&co);
        ccn_destroy(&h);
    } while (0);
    printf("link tests\n");
    do {
        struct ccn_charbuf *l = ccn_charbuf_create();
        struct ccn_charbuf *name = ccn_charbuf_create();
        struct ccn_parsed_Link pl = {0};
        struct ccn_buf_decoder decoder;
        struct ccn_buf_decoder *d;
        struct ccn_indexbuf *comps = ccn_indexbuf_create();
        printf("Unit test case %d\n", i++);
        ccn_name_from_uri(name, "ccnx:/test/link/name");
        ccnb_append_Link(l, name, "label", NULL);
        d = ccn_buf_decoder_start(&decoder, l->buf, l->length);
        res = ccn_parse_Link(d, &pl, comps);
        if (res != 3 /* components in name */) {
            printf("Failed: ccn_parse_Link res == %d\n", (int)res);
            result = 1;
        }        
    } while (0);
    
    exit(result);
}
Exemplo n.º 12
0
int
unit_tests_for_signing(struct ccn *h, int *ip, int symmetric)
{
    struct ccn_charbuf *co = ccn_charbuf_create();
    struct ccn_charbuf *co2 = ccn_charbuf_create();
    struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT;
    struct ccn_parsed_ContentObject pco = {0};
    struct ccn_parsed_ContentObject pco2 = {0};
    struct ccn_charbuf *name = ccn_charbuf_create();
    int res;
    int result = 0;

    ccn_name_from_uri(name, "ccnx:/test/data/%00%42");
    res = ccn_sign_content(h, co, name, NULL, "DATA", 4);
    if (res != 0) {
        printf("Failed: res == %d\n", (int)res);
        result = 1;
    }
    sparm.template_ccnb = ccn_charbuf_create();
    res = ccn_parse_ContentObject(co->buf, co->length, &pco, NULL);
    if (res != 0) {
        printf("Failed: ccn_parse_ContentObject res == %d\n", (int)res);
        result = 1;
        goto Bail;
    }
    ccn_charbuf_append(sparm.template_ccnb,
        co->buf + pco.offset[CCN_PCO_B_SignedInfo],
        pco.offset[CCN_PCO_E_SignedInfo] - pco.offset[CCN_PCO_B_SignedInfo]);
    sparm.sp_flags = CCN_SP_TEMPL_TIMESTAMP;
    printf("Unit test case %d\n", (*ip)++);
    res = ccn_sign_content(h, co2, name, &sparm, "DATA", 4);
    if (res != 0) {
        printf("Failed: res == %d\n", (int)res);
        result = 1;
    }
    res = ccn_parse_ContentObject(co2->buf, co2->length, &pco2, NULL);
    if (res != 0) {
        printf("Failed to parse: res == %d\n", (int)res);
        result = 1;
    }
    printf("Unit test case %d\n", (*ip)++);
    sparm.sp_flags = -1;
    res = ccn_sign_content(h, co, name, &sparm, "DATA", 4);
    if (res != -1) {
        printf("Failed: res == %d\n", (int)res);
        result = 1;
    }

    /*
     * We can run this test with symmetric keys if the problem of being able
     * to store both a keystore and its associated key in the corresponding
     * hashtables of a handle can be solved.
     */
    if (!symmetric) {
        printf("Unit test case %d\n", (*ip)++);
        res = ccn_verify_content(h, co->buf, &pco);
        if (res != 0) {
            printf("Failed: res == %d\n", (int)res);
            result = 1;
        }
    }
Bail:
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&sparm.template_ccnb); 
    ccn_charbuf_destroy(&co);
    ccn_charbuf_destroy(&co2);
    return result;
}
Exemplo n.º 13
0
/**
 * Load a link to the repo policy from the repoPolicy file and load the link
 * target to extract the actual policy.
 * If a policy file does not exist a new one is created, with a link to a policy
 * based either on the environment variable CCNR_GLOBAL_PREFIX or the system
 * default value of ccnx:/parc.com/csl/ccn/Repos, plus the system defaults for
 * other fields.
 * This routine must be called after the btree code is initialized and capable
 * of returning content objects.
 * Sets the parsed_policy field of the handle to be the new policy.
 */
static int
load_policy(struct ccnr_handle *ccnr)
{
    int fd;
    ssize_t res;
    struct content_entry *content = NULL;
    const unsigned char *content_msg = NULL;
    struct ccn_parsed_ContentObject pco = {0};
    struct ccn_parsed_Link pl = {0};
    struct ccn_indexbuf *nc = NULL;
    struct ccn_charbuf *basename = NULL;
    struct ccn_charbuf *policy = NULL;
    struct ccn_charbuf *policy_cob = NULL;
    struct ccn_charbuf *policyFileName;
    const char *global_prefix;
    const unsigned char *buf = NULL;
    size_t length = 0;
    int segment = 0;
    int final = 0;
    struct ccn_buf_decoder decoder;
    struct ccn_buf_decoder *d;
    
    policyFileName = ccn_charbuf_create();
    ccn_charbuf_putf(policyFileName, "%s/repoPolicy", ccnr->directory);
    ccnr->parsed_policy = ccnr_parsed_policy_create();
    fd = open(ccn_charbuf_as_string(policyFileName), O_RDONLY);
    if (fd >= 0) {
        ccnr->policy_link_cob = ccn_charbuf_create();
        ccn_charbuf_reserve(ccnr->policy_link_cob, 4096);   // limits the size of the policy link
        ccnr->policy_link_cob->length = 0;    // clear the buffer
        res = read(fd, ccnr->policy_link_cob->buf, ccnr->policy_link_cob->limit - ccnr->policy_link_cob->length);
        close(fd);
        if (res == -1) {
            r_init_fail(ccnr, __LINE__, "Error reading repoPolicy file.", errno);
            ccn_charbuf_destroy(&ccnr->policy_link_cob);
            ccn_charbuf_destroy(&policyFileName);
            return(-1);
        }
        ccnr->policy_link_cob->length = res;
        nc = ccn_indexbuf_create();
        res = ccn_parse_ContentObject(ccnr->policy_link_cob->buf,
                                      ccnr->policy_link_cob->length, &pco, nc);
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnr->policy_link_cob->buf,
                                  pco.offset[CCN_PCO_B_Content],
                                  pco.offset[CCN_PCO_E_Content],
                                  &buf, &length);
        d = ccn_buf_decoder_start(&decoder, buf, length);
        res = ccn_parse_Link(d, &pl, NULL);
        if (res <= 0) {
            ccnr_msg(ccnr, "Policy link is malformed.");
            goto CreateNewPolicy;
        }
        basename = ccn_charbuf_create();
        ccn_charbuf_append(basename, buf + pl.offset[CCN_PL_B_Name],
                           pl.offset[CCN_PL_E_Name] - pl.offset[CCN_PL_B_Name]);
        ccnr->policy_name = ccn_charbuf_create(); // to detect writes to this name
        ccn_charbuf_append_charbuf(ccnr->policy_name, basename); // has version
        ccn_name_chop(ccnr->policy_name, NULL, -1); // get rid of version
        policy = ccn_charbuf_create();
        // if we fail to retrieve the link target, report and then create a new one
        do {
            ccn_name_append_numeric(basename, CCN_MARKER_SEQNUM, segment++);
            content = r_store_lookup_ccnb(ccnr, basename->buf, basename->length);
            if (content == NULL) {
                ccnr_debug_ccnb(ccnr, __LINE__, "policy lookup failed for", NULL,
                                basename->buf, basename->length);
                break;
            }
            ccn_name_chop(basename, NULL, -1);
            content_msg = r_store_content_base(ccnr, content);
            if (content_msg == NULL) {
                ccnr_debug_ccnb(ccnr, __LINE__, "Unable to read policy object", NULL,
                                basename->buf, basename->length);
                break;
            }
            res = ccn_parse_ContentObject(content_msg, r_store_content_size(ccnr, content), &pco, nc);
            res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, content_msg,
                                      pco.offset[CCN_PCO_B_Content],
                                      pco.offset[CCN_PCO_E_Content],
                                      &buf, &length);
            ccn_charbuf_append(policy, buf, length);
            final = ccn_is_final_pco(content_msg, &pco, nc);
        } while (!final && segment < 100);
Exemplo n.º 14
0
/**
 * Test for a match between a ContentObject and an Interest
 *
 * @param content_object        ccnb-encoded ContentObject
 * @param content_object_size   its size in bytes
 * @param implicit_content_digest boolean indicating whether the
 *                              final name component is implicit (as in
 *                              the on-wire format) or explicit (as within
 *                              ccnd's content store).
 * @param pc                    Valid parse information may be provided to
 *                              speed things up. If NULL it will be
 *                              reconstructed internally.
 * @param interest_msg          ccnb-encoded Interest
 * @param interest_msg_size     its size in bytes
 * @param pi                    see _pc_
 *
 * @result 1 if the ccnb-encoded content_object matches the 
 *           ccnb-encoded interest_msg, otherwise 0.
 */
int
ccn_content_matches_interest(const unsigned char *content_object,
                             size_t content_object_size,
                             int implicit_content_digest,
                             struct ccn_parsed_ContentObject *pc,
                             const unsigned char *interest_msg,
                             size_t interest_msg_size,
                             const struct ccn_parsed_interest *pi)
{
    struct ccn_parsed_ContentObject pc_store;
    struct ccn_parsed_interest pi_store;
    int res;
    int ncomps;
    int prefixstart;
    int prefixbytes;
    int namecompstart;
    int namecompbytes;
    int checkdigest = 0;
    struct ccn_buf_decoder decoder;
    struct ccn_buf_decoder *d;
    const unsigned char *nextcomp;
    size_t nextcomp_size = 0;
    const unsigned char *comp;
    size_t comp_size = 0;
    const unsigned char *bloom;
    size_t bloom_size = 0;
    unsigned char match_any[2] = "-";
    if (pc == NULL) {
        res = ccn_parse_ContentObject(content_object, content_object_size,
                                      &pc_store, NULL);
        if (res < 0) return(0);
        pc = &pc_store;
    }
    if (pi == NULL) {
        res = ccn_parse_interest(interest_msg, interest_msg_size,
                                 &pi_store, NULL);
        if (res < 0) return(0);
        pi = &pi_store;
    }
    if (!ccn_pubid_matches(content_object, pc, interest_msg, pi))
        return(0);
    ncomps = pc->name_ncomps + (implicit_content_digest ? 1 : 0);
    if (ncomps < pi->prefix_comps + pi->min_suffix_comps)
        return(0);
    if (ncomps > pi->prefix_comps + pi->max_suffix_comps)
        return(0);
    prefixstart = pi->offset[CCN_PI_B_Component0];
    prefixbytes = pi->offset[CCN_PI_E_LastPrefixComponent] - prefixstart;
    namecompstart = pc->offset[CCN_PCO_B_Component0];
    namecompbytes = pc->offset[CCN_PCO_E_ComponentLast] - namecompstart;
    if (prefixbytes > namecompbytes) {
        /*
         * The only way for this to be a match is if the implicit
         * content digest name component comes into play.
         */
        if (implicit_content_digest &&
            pi->offset[CCN_PI_B_LastPrefixComponent] - prefixstart == namecompbytes &&
            (pi->offset[CCN_PI_E_LastPrefixComponent] -
             pi->offset[CCN_PI_B_LastPrefixComponent]) == 1 + 2 + 32 + 1) {
            prefixbytes = namecompbytes;
            checkdigest = 1;
        }
        else
            return(0);
    }
    if (0 != memcmp(interest_msg + prefixstart,
                    content_object + namecompstart,
                    prefixbytes))
        return(0);
    if (checkdigest) {
        /*
         * The Exclude by next component is not relevant in this case,
         * since there is no next component present.
         */
        ccn_digest_ContentObject(content_object, pc);
        d = ccn_buf_decoder_start(&decoder,
                        interest_msg + pi->offset[CCN_PI_B_LastPrefixComponent],
                        (pi->offset[CCN_PI_E_LastPrefixComponent] -
                         pi->offset[CCN_PI_B_LastPrefixComponent]));
        comp_size = 0;
        if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
                ccn_buf_advance(d);
                ccn_buf_match_blob(d, &comp, &comp_size);
            }
        if (comp_size != pc->digest_bytes) abort();
        if (0 != memcmp(comp, pc->digest, comp_size))
            return(0);
    }
    else if (pi->offset[CCN_PI_E_Exclude] > pi->offset[CCN_PI_B_Exclude]) {
        if (prefixbytes < namecompbytes) {
            /* pick out the next component in the content object name */
            d = ccn_buf_decoder_start(&decoder,
                                      content_object +
                                        (namecompstart + prefixbytes),
                                      pc->offset[CCN_PCO_E_ComponentLast] -
                                        (namecompstart + prefixbytes));
            if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
                ccn_buf_advance(d);
                ccn_buf_match_blob(d, &nextcomp, &nextcomp_size);
            }
            else
                return(0);
        }
        else if (!implicit_content_digest)
            goto exclude_checked;
        else if (prefixbytes == namecompbytes) {
            /* use the digest name as the next component */
            ccn_digest_ContentObject(content_object, pc);
            nextcomp_size = pc->digest_bytes;
            nextcomp = pc->digest;
        }
        else abort(); /* bug - should have returned already */
        d = ccn_buf_decoder_start(&decoder,
                                  interest_msg + pi->offset[CCN_PI_B_Exclude],
                                  pi->offset[CCN_PI_E_Exclude] -
                                  pi->offset[CCN_PI_B_Exclude]);
        if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude))
            abort();
        ccn_buf_advance(d);
        bloom = NULL;
        bloom_size = 0;
        if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
                ccn_buf_advance(d);
                bloom = match_any;
                ccn_buf_check_close(d);
        }
        else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
                ccn_buf_advance(d);
                if (ccn_buf_match_blob(d, &bloom, &bloom_size))
                    ccn_buf_advance(d);
                ccn_buf_check_close(d);
        }
        while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
            ccn_buf_advance(d);
            comp_size = 0;
            if (ccn_buf_match_blob(d, &comp, &comp_size))
                ccn_buf_advance(d);
            ccn_buf_check_close(d);
            if (comp_size > nextcomp_size)
                break;
            if (comp_size == nextcomp_size) {
                res = memcmp(comp, nextcomp, comp_size);
                if (res == 0)
                    return(0); /* One of the explicit excludes */
                if (res > 0)
                    break;
            }
            bloom = NULL;
            bloom_size = 0;
            if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
                ccn_buf_advance(d);
                bloom = match_any;
                ccn_buf_check_close(d);
            }
            else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
                ccn_buf_advance(d);
                if (ccn_buf_match_blob(d, &bloom, &bloom_size))
                    ccn_buf_advance(d);
                ccn_buf_check_close(d);
            }
        }
        /*
         * Now we have isolated the applicable filter (Any or Bloom or none).
         */
        if (bloom == match_any)
            return(0);
        else if (bloom_size != 0) {
            const struct ccn_bloom_wire *f = ccn_bloom_validate_wire(bloom, bloom_size);
            /* If not a valid filter, treat like a false positive */
            if (f == NULL)
                return(0);
            if (ccn_bloom_match_wire(f, nextcomp, nextcomp_size))
                return(0);
        }
    exclude_checked: {}
    }
    /*
     * At this point the prefix matches and exclude-by-next-component is done.
     */
    // test any other qualifiers here
    return(1);
}