Esempio n. 1
0
/*
 * Utility routine to set the topo and prefix fields to copies of the
 * passed in charbufs
 */
int
ccns_slice_set_topo_prefix(struct ccns_slice *s,
                           struct ccn_charbuf *t,
                           struct ccn_charbuf *p) {
    int res = 0;
    if (t != NULL) {
        ccn_charbuf_reset(s->topo);
        res |= ccn_charbuf_append_charbuf(s->topo, t);
    }
    if (p != NULL) {
        ccn_charbuf_reset(s->prefix);
        res |= ccn_charbuf_append_charbuf(s->prefix, p);
    }
    return(res);
}
Esempio n. 2
0
/**
 * Append to a charbuf the versioned ccnb-encoded Name that will be used for
 * this stream.
 *
 * @param w the seqwriter for which the name is requested
 * @param nv the charbuf to which the name will be appended
 * @returns 0 for success, -1 for failure
 */
int
ccn_seqw_get_name(struct ccn_seqwriter *w, struct ccn_charbuf *nv)
{
    if (nv == NULL || w == NULL)
        return (-1);
    return (ccn_charbuf_append_charbuf(nv, w->nv));
}
Esempio n. 3
0
/*
 * Utility routine to add a clause to a ccns_slice structure
 */
int
ccns_slice_add_clause(struct ccns_slice *s, struct ccn_charbuf *c) {
    struct ccn_charbuf **clauses = NULL;
    struct ccn_charbuf *clause;
    clause = ccn_charbuf_create_n(c->length);
    if (clause == NULL)
        return(-1);
    if (s->clauses == NULL) {
        s->clauses = calloc(1, sizeof(s->clauses[0]));
        if (s->clauses == NULL)
            goto Cleanup;
    } else {
        clauses = realloc(s->clauses, (s->nclauses + 1) * sizeof(s->clauses[0]));
        if (clauses == NULL)
            goto Cleanup;
        s->clauses = clauses;
    }
    ccn_charbuf_append_charbuf(clause, c);
    s->clauses[s->nclauses++] = clause;
    return (0);

Cleanup:
    ccn_charbuf_destroy(&clause);
    return (-1);
}
Esempio n. 4
0
/**
 * Post an interests to the CCN network, and maintains the state information
 *
 * This will create the name used to express the interest on the network. It takes
 * the given segment and includes it in the name. It will then manage the state information
 * we keep in the context to allow us to deliver segments in order, as oppose to how
 * they may be presented to us from the network.
 *
 * \param me		context holding the array of interest states and other ccn information
 * \param seg		the segment to express interest in
 * \return status value from the express call made to CCN
 */
static gint
request_segment (Gstccnxsrc * me, uintmax_t seg)
{
  struct ccn_charbuf *nm = NULL;
  gint rc = 0;

  if (NULL == me)
    return -1;

  // nm = sequenced_name(me->p_name, seg);
  nm = ccn_charbuf_create ();
  rc |= ccn_charbuf_append_charbuf (nm, me->p_name);
  rc |= ccn_name_append_numeric (nm, CCN_MARKER_SEQNUM, seg);

  GST_INFO ("reqseg - name for interest...");
  // hDump(nm->buf, nm->length);
  rc |= ccn_express_interest (me->ccn, nm, me->ccn_closure, me->p_template);
  ccn_charbuf_destroy (&nm);
  if (rc < 0) {
    return rc;
  }

  GST_DEBUG ("interest sent for segment %d\n", seg);
  return rc;
}
Esempio n. 5
0
int
andana_server_connect(struct andana_server *server)
{
    int res;
    res = ccn_proxy_connect(server->proxy);

    if (res != 0) {
        return(res);
    }

    struct ccn_charbuf *session_namespace = ccn_charbuf_create();
    ccn_charbuf_append_charbuf(session_namespace, server->proxy->filter);
    ccn_name_append_str(session_namespace, "CREATESESSION");

    server->session_handler.p = &andana_server_session_listener;
    server->session_handler.data = server;

    res = ccn_set_interest_filter(server->proxy->handle,
                                  session_namespace,
                                  &(server->session_handler));

    ccn_charbuf_destroy(&session_namespace);

    return(res);
}
Esempio n. 6
0
/**
 * Write a ccns_slice object to a repository.
 * @param h is the ccn_handle on which to write.
 * @param slice is a pointer to a ccns_slice object to be written.
 * @param name, if non-NULL, is a pointer to a charbuf which will be filled
 *  in with the name of the slice that was written.
 * @returns 0 on success, -1 otherwise.
 */
int
ccns_write_slice(struct ccn *h,
                 struct ccns_slice *slice,
                 struct ccn_charbuf *name) {
    struct ccn_charbuf *n = NULL;
    int res;
    // calculate versioned and segmented name for the slice
    n = ccn_charbuf_create();
    if (n == NULL)
        return(-1);
    res = ccns_slice_name(n, slice);
    if (res < 0)
        goto Cleanup;
    res |= ccn_create_version(h, n, CCN_V_NOW, 0, 0);
    if (name != NULL) {
        ccn_charbuf_reset(name);
        res |= ccn_charbuf_append_charbuf(name, n);
    }
    res |= ccn_name_append_numeric(n, CCN_MARKER_SEQNUM, 0);
    if (res < 0)
        goto Cleanup;
    res = write_slice(h, slice, n);

Cleanup:
    ccn_charbuf_destroy(&n);
    return (res);
}
Esempio n. 7
0
static void
setCurrentHash(struct SyncRootStruct *root, struct SyncHashCacheEntry *ce) {
    struct ccn_charbuf *hash = root->currentHash;
    hash->length = 0;
    if (ce != NULL)
        ccn_charbuf_append_charbuf(hash, ce->hash);
}
Esempio n. 8
0
static struct ccn_charbuf *
ccnr_init_service_ccnb(struct ccnr_handle *ccnr, struct ccn *h, const char *baseuri, int freshness)
{
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
    struct ccn_charbuf *name = ccn_charbuf_create();
    struct ccn_charbuf *pubid = ccn_charbuf_create();
    struct ccn_charbuf *pubkey = ccn_charbuf_create();
    struct ccn_charbuf *keyid = ccn_charbuf_create();
    struct ccn_charbuf *cob = ccn_charbuf_create();
    int res;
    
    res = ccn_get_public_key(h, NULL, pubid, pubkey);
    if (res < 0) abort();
    ccn_name_from_uri(name, baseuri);
    ccn_charbuf_append_value(keyid, CCN_MARKER_CONTROL, 1);
    ccn_charbuf_append_string(keyid, ".M.K");
    ccn_charbuf_append_value(keyid, 0, 1);
    ccn_charbuf_append_charbuf(keyid, pubid);
    ccn_name_append(name, keyid->buf, keyid->length);
    ccn_create_version(h, name, 0, ccnr->starttime, ccnr->starttime_usec * 1000);
    sp.template_ccnb = ccn_charbuf_create();
    ccnb_element_begin(sp.template_ccnb, CCN_DTAG_SignedInfo);
    ccnb_element_begin(sp.template_ccnb, CCN_DTAG_KeyLocator);
    ccnb_element_begin(sp.template_ccnb, CCN_DTAG_KeyName);
    ccn_charbuf_append_charbuf(sp.template_ccnb, name);
    ccnb_element_end(sp.template_ccnb);
//    ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_PublisherPublicKeyDigest,
//                          CCN_DTAG);
//    ccn_charbuf_append_charbuf(sp.template_ccnb, pubid);
//    ccnb_element_end(sp.template_ccnb);
    ccnb_element_end(sp.template_ccnb);
    ccnb_element_end(sp.template_ccnb);
    sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR;
    ccn_name_from_uri(name, "%00");
    sp.sp_flags |= CCN_SP_FINAL_BLOCK;
    sp.type = CCN_CONTENT_KEY;
    sp.freshness = freshness;
    res = ccn_sign_content(h, cob, name, &sp, pubkey->buf, pubkey->length);
    if (res != 0) abort();
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&pubid);
    ccn_charbuf_destroy(&pubkey);
    ccn_charbuf_destroy(&keyid);
    ccn_charbuf_destroy(&sp.template_ccnb);
    return(cob);
}
Esempio n. 9
0
static struct ccn_charbuf *
sequenced_name(struct ccn_charbuf *basename, seg_t seq) {
    // creates a new struct ccn_charbuf *, appending the sequence number to the basename
	struct ccn_charbuf *name = ccn_charbuf_create();
    ccn_charbuf_append_charbuf(name, basename);
	if (seq >= 0)
		ccn_name_append_numeric(name, CCN_MARKER_SEQNUM, seq);
    return(name);
}
Esempio n. 10
0
/*
 * utility, may need to be exported, to append the encoding of a
 * slice to a charbuf
 */
static int
append_slice(struct ccn_charbuf *c, struct ccns_slice *s) {
    int res = 0;
    int i;

    res |= ccnb_element_begin(c, CCN_DTAG_SyncConfigSlice);
    res |= ccnb_tagged_putf(c, CCN_DTAG_SyncVersion, "%u", SLICE_VERSION);
    res |= ccn_charbuf_append_charbuf(c, s->topo);
    res |= ccn_charbuf_append_charbuf(c, s->prefix);
    res |= ccnb_element_begin(c, CCN_DTAG_SyncConfigSliceList);
    for (i = 0; i < s->nclauses ; i++) {
        res |= ccnb_tagged_putf(c, CCN_DTAG_SyncConfigSliceOp, "%u", 0);
        res |= ccn_charbuf_append_charbuf(c, s->clauses[i]);
    }
    res |= ccnb_element_end(c);
    res |= ccnb_element_end(c);
    return (res);
}
Esempio n. 11
0
static struct andana_server_pair *
andana_server_pair_init(struct ccn_charbuf *name, struct ccn_pkey *symkey)
{
    struct andana_server_pair *p =
        calloc(1, sizeof(struct andana_server_pair));

    p->name = ccn_charbuf_create();
    ccn_charbuf_append_charbuf(p->name, name);

    p->symkey = ccn_crypto_symkey_copy(symkey);

    return(p);
}
Esempio n. 12
0
/**
 * Append a representation of a Link to a charbuf.
 * @param buf is the output buffer where encoded link is written.
 * @param name is the ccnb-encoded name from ccn_name_init and friends.
 * @param label is a UTF-8 string in a ccn_charbuf.
 * @param linkAuthenticator is the ccnb-encoded LinkAuthenticator.
 * @returns 0 for success or -1 for error.
 */
int
ccnb_append_Link(struct ccn_charbuf *buf,
                 const struct ccn_charbuf *name,
                 const char *label,
                 const struct ccn_charbuf *linkAuthenticator
                 )
{
    int res = 0;
    
    res |= ccn_charbuf_append_tt(buf, CCN_DTAG_Link, CCN_DTAG);
    res |= ccn_charbuf_append_charbuf(buf, name);
    if (label != NULL) {
        res |= ccn_charbuf_append_tt(buf, CCN_DTAG_Label, CCN_DTAG);
        res |= ccn_charbuf_append_tt(buf, strlen(label), CCN_UDATA);
        res |= ccn_charbuf_append_string(buf, label);
        res |= ccn_charbuf_append_closer(buf);
    }
    if (linkAuthenticator != NULL) {
        res |= ccn_charbuf_append_charbuf(buf, linkAuthenticator);
    }
    res |= ccn_charbuf_append_closer(buf);
    return(res == 0 ? 0 : -1);
}
Esempio n. 13
0
/**
 * should probably return a new cob, rather than reusing one.
 * should publish link as:
 *    CCNRID_POLICY_URI("ccnx:/%C1.M.S.localhost/%C1.M.SRV/repository/POLICY)/%C1.M.K--pubid--/--version--/%00
 * should have key locator which is the key name of the repository
 */
PUBLIC struct ccn_charbuf *
ccnr_init_policy_link_cob(struct ccnr_handle *ccnr, struct ccn *h,
                          struct ccn_charbuf *targetname)
{
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
    struct ccn_charbuf *name = ccn_charbuf_create();
    struct ccn_charbuf *pubid = ccn_charbuf_create();
    struct ccn_charbuf *pubkey = ccn_charbuf_create();
    struct ccn_charbuf *keyid = ccn_charbuf_create();
    struct ccn_charbuf *content = ccn_charbuf_create();
    struct ccn_charbuf *cob = ccn_charbuf_create();
    struct ccn_charbuf *answer = NULL;
    int res;
    
    res = ccn_get_public_key(h, NULL, pubid, pubkey);
    if (res < 0)
        goto Bail;
    if (ccn_name_from_uri(name, CCNRID_POLICY_URI) < 0)
        goto Bail;
    res |= ccn_charbuf_append_value(keyid, CCN_MARKER_CONTROL, 1);
    res |= ccn_charbuf_append_string(keyid, ".M.K");
    res |= ccn_charbuf_append_value(keyid, 0, 1);
    res |= ccn_charbuf_append_charbuf(keyid, pubid);
    res |= ccn_name_append(name, keyid->buf, keyid->length);
    res |= ccn_create_version(h, name, CCN_V_NOW, 0, 0);
    if (ccn_name_from_uri(name, "%00") < 0)
        goto Bail;
    sp.sp_flags |= CCN_SP_FINAL_BLOCK;
    sp.type = CCN_CONTENT_LINK;
    res |= ccnb_append_Link(content, targetname, "Repository Policy", NULL);
    if (res != 0)
        goto Bail;
    res |= ccn_sign_content(h, cob, name, &sp, content->buf, content->length);
    if (res != 0)
        goto Bail;
    answer = cob;
    cob = NULL;
    
Bail:
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&pubid);
    ccn_charbuf_destroy(&pubkey);
    ccn_charbuf_destroy(&keyid);
    ccn_charbuf_destroy(&content);
    ccn_charbuf_destroy(&cob);
    return (answer);
}
// 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);
}
Esempio n. 15
0
/**
 * Delete a ccns_slice object from a repository.
 * @param h is the ccn_handle on which to write.
 * @param name is a pointer to a charbuf naming the slice to be deleted.
 * @returns 0 on success, -1 otherwise.
 */
int
ccns_delete_slice(struct ccn *h, struct ccn_charbuf *name) {
    struct ccn_charbuf *n = NULL;
    int res = 0;

    // calculate versioned and segmented name for the slice
    n = ccn_charbuf_create_n(32 + name->length);
    if (n == NULL)
        return(-1);
    res |= ccn_charbuf_append_charbuf(n, name);
    res |= ccn_create_version(h, n, CCN_V_NOW | CCN_V_REPLACE, 0, 0);
    res |= ccn_name_append_numeric(n, CCN_MARKER_SEQNUM, 0);
    if (res >= 0)
        res = write_slice(h, NULL, n);
    ccn_charbuf_destroy(&n);
    return (res);
}
int sign_interest(struct ccn_charbuf* name_signed, struct ccn_charbuf* name,
			struct ccn_charbuf* signed_info, const char* digest_algorithm, struct ccn_pkey* key) {

	int res = 0;
	// Now assemble a signed Content object
	// Use ccn_encode_ContentObject so we can specify the key of our choice
	struct ccn_charbuf *tempContentObj = ccn_charbuf_create();
	res = ccn_encode_ContentObject(tempContentObj, name, signed_info, NULL /* no data */, 0,
								   digest_algorithm, key);
	if (res < 0) {
		fprintf(stderr, "Error building content object (res == %d)\n", res);
		return(res);
	}
	// Call replace_name to knock out the name;
	// it would be more efficient to assemble this with no name a modified ccn_encode_ContentObject() call
	// but that requires modification to the library function
	struct ccn_charbuf *empty_name = ccn_charbuf_create();
	struct ccn_charbuf *sigContentObj = ccn_charbuf_create();
	ccn_name_init(empty_name);
	// First prepend the namespace; (should this be done as a "name component"?)
	ccn_charbuf_append(sigContentObj, NS_SIGNATURE, NS_SIGNATURE_LEN);
	replace_name(sigContentObj, tempContentObj->buf, tempContentObj->length, empty_name);
	//fprintf(stderr, "replace_name == %d (%s)\n", res, (res==0)?"ok":"fail");
	/*
	// Check that we didn't break things
	struct ccn_parsed_ContentObject pco = {0};
	res = ccn_parse_ContentObject(&sigContentObj->buf[NS_SIGNATURE_LEN], sigContentObj->length - NS_SIGNATURE_LEN, &pco, NULL);
	if (res < 0) {
		fprintf(stderr, "Error parsing built content object (res == %d)\n", res);
		return(1);
	}
	*/
	ccn_charbuf_destroy(&empty_name);
	ccn_charbuf_destroy(&tempContentObj);

	// Build the final name for the interest  <prefix>/<namespace><contentObj>
	ccn_charbuf_append_charbuf(name_signed, name); // Copy the name
	ccn_name_append(name_signed, sigContentObj->buf, sigContentObj->length);  // Concatenate the new component
    // Dump the signature
    // print_hex(stderr,&(sigContentObj->buf)[NS_SIGNATURE_LEN],sigContentObj->length - NS_SIGNATURE_LEN,12);
    // fprintf(stderr,"\n");
	//
	ccn_charbuf_destroy(&sigContentObj);
	return (res);
}
Esempio n. 17
0
/**
 * Request the current segment number from the ccnx data producer
 *
 * This is a request for meta data for the media stream the user has named with their URI.
 * We assume that they want to join the media broadcast from what is currently being published
 * and \em not want to start from the beginning...although there is good reason for that too.
 *
 * Getting this data is done by expressing interests in the meta data. The producer of the
 * media stream will catch this through one of its ccnx filters and produce this meta data
 * back through the network to us.
 *
 * \param h		ccnx context handle
 * \param name	the content name for which we desire the meta data
 * \param timeout	how long to wait around
 * \return the segment number to ask for first, 0 on timeout
 */
static uintmax_t *
get_segment (struct ccn *h, struct ccn_charbuf *name, int timeout)
{
  struct ccn_charbuf *hn;
  uintmax_t *result = NULL;
  int res = 0;

  GST_INFO ("get_segment step 1");
  hn = ccn_charbuf_create ();
  // ccn_name_append_components(hn, name->buf, 0, name->length );
  ccn_charbuf_append_charbuf (hn, name);
  ccn_name_from_uri (hn, "_meta_/.segment");
  // ccn_name_append_str(hn, "_meta_");
  // ccn_name_append_str(hn, ".segment");
  GST_INFO ("get_segment step 2");
  // res = ccn_resolve_version(h, hn, CCN_V_HIGHEST, timeout);
  GST_INFO ("get_segment step 3, res: %d", res);
  if (res == 0) {
    struct ccn_charbuf *ho = ccn_charbuf_create ();
    struct ccn_parsed_ContentObject pcobuf = { 0 };
    const unsigned char *hc;
    size_t hcs;

    // hDump(DUMP_ADDR(hn->buf), DUMP_SIZE(hn->length));
    GST_INFO ("get_segment step 10");
    res = ccn_get (h, hn, NULL, timeout, ho, &pcobuf, NULL, 0);
    GST_INFO ("get_segment step 11, res: %d", res);
    if (res >= 0) {
      hc = ho->buf;
      hcs = ho->length;
      // hDump( DUMP_ADDR(hc), DUMP_SIZE(hcs));
      ccn_content_get_value (hc, hcs, &pcobuf, &hc, &hcs);
      // hDump( DUMP_ADDR(hc), DUMP_SIZE(hcs));
      result = calloc (1, sizeof (uintmax_t));
      memcpy (result, hc, sizeof (uintmax_t));
    }
    ccn_charbuf_destroy (&ho);
  }
  GST_INFO ("get_segment step 9");
  ccn_charbuf_destroy (&hn);
  return (result);
}
Esempio n. 18
0
/**
 * Read a slice (from a repository) given the name.
 * @param h is the ccn_handle on which to read.
 * @param name is the charbuf containing the name of the sync slice to be read.
 * @param slice is a pointer to a ccns_slice object which will be filled in
 *  on successful return.
 * @returns 0 on success, -1 otherwise.
 */
int
ccns_read_slice(struct ccn *h, struct ccn_charbuf *name,
                struct ccns_slice *slice) {
    struct ccn_parsed_ContentObject pco_space = { 0 };
    struct ccn_parsed_ContentObject *pco = &pco_space;
    struct ccn_charbuf *nc = ccn_charbuf_create_n(name->length);
    struct ccn_charbuf *cob = ccn_charbuf_create();
    const unsigned char *content;
    size_t content_length;
    int res = -1;

    if (nc == NULL || cob == NULL)
        goto Cleanup;

    ccn_charbuf_append_charbuf(nc, name);
    res = ccn_resolve_version(h, nc,  CCN_V_HIGHEST, 100); // XXX: timeout
    if (res < 0)
        goto Cleanup;
    if (res == 0) {
        // TODO: check if the last component is a segment number, chop it off, try again.
    }
    res = ccn_get(h, nc, NULL, 100, cob, pco, NULL, 0);
    if (res < 0)
        goto Cleanup;
    if (pco->type != CCN_CONTENT_DATA) {
        res = -1;
        goto Cleanup;
    }
    res = ccn_content_get_value(cob->buf, cob->length, pco,
                                &content, &content_length);
    if (res < 0)
        goto Cleanup;
    res = slice_parse(slice, content, content_length);

Cleanup:
    ccn_charbuf_destroy(&nc);
    ccn_charbuf_destroy(&cob);
    return (res);
}
Esempio n. 19
0
static struct ccn_charbuf *
ccnr_init_policy_cob(struct ccnr_handle *ccnr, struct ccn *h,
                     struct ccn_charbuf *basename,
                     int freshness, struct ccn_charbuf *content)
{
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
    struct ccn_charbuf *name = ccn_charbuf_create();
    struct ccn_charbuf *pubid = ccn_charbuf_create();
    struct ccn_charbuf *pubkey = ccn_charbuf_create();
    struct ccn_charbuf *keyid = ccn_charbuf_create();
    struct ccn_charbuf *tcob = ccn_charbuf_create();
    struct ccn_charbuf *cob = NULL;          // result
    int res;
    
    res = ccn_get_public_key(h, NULL, pubid, pubkey);
    if (res < 0) 
        goto Leave;
    res = ccn_charbuf_append_charbuf(name, basename);
    if (ccn_name_from_uri(name, "%00") < 0)
        goto Leave;
    sp.sp_flags |= CCN_SP_FINAL_BLOCK;
    sp.type = CCN_CONTENT_DATA;
    sp.freshness = freshness;
    res |= ccn_sign_content(h, tcob, name, &sp, content->buf, content->length);
    if (res == 0) {
        cob = tcob;
        tcob = NULL;
    }
    
Leave:
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&pubid);
    ccn_charbuf_destroy(&pubkey);
    ccn_charbuf_destroy(&keyid);
    ccn_charbuf_destroy(&tcob);
    return (cob);
}
Esempio n. 20
0
/**
 * Encode and sign a ContentObject.
 * @param buf is the output buffer where encoded object is written.
 * @param Name is the ccnb-encoded name from ccn_name_init and friends.
 * @param SignedInfo is the ccnb-encoded info from ccn_signed_info_create.
 * @param data pintes to the raw data to be encoded.
 * @param size is the size, in bytes, of the raw data to be encoded.
 * @param digest_algorithm may be NULL for default.
 * @param private_key is the private key to use for signing.
 * @returns 0 for success or -1 for error.
 */
int
ccn_encode_ContentObject(struct ccn_charbuf *buf,
                         const struct ccn_charbuf *Name,
                         const struct ccn_charbuf *SignedInfo,
                         const void *data,
                         size_t size,
                         const char *digest_algorithm,
                         const struct ccn_pkey *private_key
                         )
{
    int res = 0;
    struct ccn_sigc *sig_ctx;
    struct ccn_signature *signature;
    size_t signature_size;
    struct ccn_charbuf *content_header;
    size_t closer_start;

    content_header = ccn_charbuf_create();
    res |= ccn_charbuf_append_tt(content_header, CCN_DTAG_Content, CCN_DTAG);
    if (size != 0)
        res |= ccn_charbuf_append_tt(content_header, size, CCN_BLOB);
    closer_start = content_header->length;
    res |= ccn_charbuf_append_closer(content_header);
    if (res < 0)
        return(-1);
    sig_ctx = ccn_sigc_create();
    if (sig_ctx == NULL)
        return(-1);
    if (0 != ccn_sigc_init(sig_ctx, digest_algorithm, private_key))
        return(-1);
    if (0 != ccn_sigc_update(sig_ctx, Name->buf, Name->length))
        return(-1);
    if (0 != ccn_sigc_update(sig_ctx, SignedInfo->buf, SignedInfo->length))
        return(-1);
    if (0 != ccn_sigc_update(sig_ctx, content_header->buf, closer_start))
        return(-1);
    if (0 != ccn_sigc_update(sig_ctx, data, size))
        return(-1);
    if (0 != ccn_sigc_update(sig_ctx, content_header->buf + closer_start,
                             content_header->length - closer_start))
        return(-1);
    signature = calloc(1, ccn_sigc_signature_max_size(sig_ctx, private_key));
    if (signature == NULL)
        return(-1);
    res = ccn_sigc_final(sig_ctx, signature, &signature_size, private_key);
    if (0 != res) {
        free(signature);
        return(-1);
    }
    ccn_sigc_destroy(&sig_ctx);
    res |= ccn_charbuf_append_tt(buf, CCN_DTAG_ContentObject, CCN_DTAG);
    res |= ccn_encode_Signature(buf, digest_algorithm,
                                NULL, 0, signature, signature_size);
    res |= ccn_charbuf_append_charbuf(buf, Name);
    res |= ccn_charbuf_append_charbuf(buf, SignedInfo);
    res |= ccnb_append_tagged_blob(buf, CCN_DTAG_Content, data, size);
    res |= ccn_charbuf_append_closer(buf);
    free(signature);
    ccn_charbuf_destroy(&content_header);
    return(res == 0 ? 0 : -1);
}
Esempio n. 21
0
int main(int argc, char** argv) {
	int res = 0;
	struct ccn* ccn_pub;
	struct ccn* ccn_rec;

	// Will hold the public/private key used for signing
	struct ccn_pkey* public_key = NULL;
	struct ccn_pkey* private_key = NULL;

	int complete=0;
	int outstanding_interests=0;

	// We need two ccn handles because the same handle cannot be used
	// to answer interests it issues.
	//
	ccn_pub = ccn_create();
    if (ccn_connect(ccn_pub, NULL) == -1) {
        fprintf(stderr, "Could not connect to ccnd");
        return(1);
    }
    ccn_rec = ccn_create();
    if (ccn_connect(ccn_rec, NULL) == -1) {
        fprintf(stderr, "Could not connect to ccnd");
        return(1);
    }

    // Closure to handle upcalls
    struct ccn_closure *cl = NULL;
    cl = (struct ccn_closure*) calloc(1, sizeof(struct ccn_closure));
    cl->p = &packet_handler;
    handler_data h_data = { &complete, &outstanding_interests, &public_key, &ccn_pub, &ccn_rec};
    cl->data = &h_data;

    // Setup our one test name without signature
    // The nonce here is just a random string, to avoid content store caching
    struct ccn_charbuf* name;
    name = ccn_charbuf_create();
    ccn_name_from_uri(name, TEST_URI);
    ccn_name_append_nonce(name);
    fprintf(stderr, "Our name: %s/<nonce>\n", TEST_URI);

    // Set up a filter for interests in that name
    res = ccn_set_interest_filter(ccn_pub, name, cl);
    if (res < 0) {
        fprintf(stderr, "Failed to register interest (res == %d)\n", res);
        return(1);
    }

    // Get our default keys -- Why do we have to do all this work??
    // Borrowed from ccn_client.c
    struct ccn_signing_params name_sp = CCN_SIGNING_PARAMS_INIT;
    struct ccn_signing_params p = CCN_SIGNING_PARAMS_INIT;
    struct ccn_keystore *keystore = NULL;
    struct ccn_charbuf *timestamp = NULL;
    struct ccn_charbuf *finalblockid = NULL;
    struct ccn_charbuf *keylocator = NULL;
    unsigned char* public_key_digest = NULL;
    size_t public_key_digest_length = 0;
    res = ccn_chk_signing_params(ccn_pub, &name_sp, &p, &timestamp, &finalblockid, &keylocator);
    if (res < 0)
        return(res);

    // For this test, use our default signing keys
    get_default_keys(ccn_pub, &p, &keystore,
    		&public_key, &public_key_digest, &public_key_digest_length, &private_key);

    // We'll need  a KeyLocator for our ContentObject
	// So continue borrowed code
	/* Construct a key locator containing the key itself */
    build_keylocator_from_key(&keylocator, public_key);

    // And a SignedInfo too
    struct ccn_charbuf *signed_info = ccn_charbuf_create();
    res = ccn_signed_info_create(signed_info,
    		 public_key_digest,
    		 public_key_digest_length,
			 timestamp,
			 p.type,
			 p.freshness,
			 0,  /* FinalBlockID is optional */
			 keylocator);

    // * Test using interests for a name that has one more component than our registered prefix
    // This is more representative of real apps...
    // 20-May-2011
    ccn_name_append_str(name, "some stuff in a name component");
    ccn_name_append_nonce(name);
    ccn_name_append_nonce(name);

    // Sign the interest
    struct ccn_charbuf *name_signed = ccn_charbuf_create();
    sign_interest(name_signed, name, signed_info, NULL /* default digest alg */, private_key);

    // Express the signed interest from a different ccn handle so we get the packet
    res = ccn_express_interest(ccn_rec, name_signed, cl, NULL);			// TODO: AnswerOriginKind could limit to signed interest?
    outstanding_interests++;

    // Express an interest with an incorrect namespace
    struct ccn_charbuf *name_signed_copy = ccn_charbuf_create();
    ccn_charbuf_append_charbuf(name_signed_copy, name_signed);
    size_t k = name->length + 10; // Seek into the namespace part of the buffer
    name_signed_copy->buf[k] = name_signed_copy->buf[k] + 1;
    res = ccn_express_interest(ccn_rec, name_signed_copy, cl, NULL);			// TODO: AnswerOriginKind could limit to signed interest?
    outstanding_interests++;

    // Express an interest with bogus signature
    name_signed_copy = ccn_charbuf_create();
    ccn_charbuf_append_charbuf(name_signed_copy, name_signed);
    k = name->length + 30;  // Seek into the signature part of the buffer
    name_signed_copy->buf[k] = name_signed_copy->buf[k] + 1;
    res = ccn_express_interest(ccn_rec, name_signed_copy, cl, NULL);			// TODO: AnswerOriginKind could limit to signed interest?
    outstanding_interests++;

    if (res < 0) {
    	fprintf(stderr, "Error expressing interest (res == %d)\n", res);
    }
    cl = NULL;  						// freed by ccn?

    while(!complete && outstanding_interests>0) {
    	// Not sure how to handle two ccn_runs?
        ccn_run(ccn_rec, 100); /* stop if we run dry for .1 sec */
        ccn_run(ccn_pub, 100); /* stop if we run dry for .1 sec */
        fflush(stdout);
    }

    ccn_charbuf_destroy(&timestamp);
    ccn_charbuf_destroy(&keylocator);
    ccn_charbuf_destroy(&finalblockid);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&name_signed);
    ccn_charbuf_destroy(&name_signed_copy);
    ccn_destroy(&ccn_pub);
    ccn_destroy(&ccn_rec);
    fflush(stderr);
	return(0);
}
Esempio n. 22
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);
Esempio n. 23
0
static int
write_slice(struct ccn *h,
            struct ccns_slice *slice,
            struct ccn_charbuf *name) {
    struct ccn_charbuf *content = NULL;
    unsigned char *cbuf = NULL;
    size_t clength = 0;
    struct ccn_charbuf *sw = NULL;
    struct ccn_charbuf *templ = NULL;
    struct ccn_charbuf *cob = NULL;
    struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT;
    struct ccn_closure *wc = NULL;
    int res;

    sw = ccn_charbuf_create_n(32 + name->length);
    if (sw == NULL) {
        res = -1;
        goto Cleanup;
    }
    ccn_charbuf_append_charbuf(sw, name);
    ccn_name_chop(sw, NULL, -1); // remove segment number
    ccn_name_from_uri(sw, "%C1.R.sw");
    ccn_name_append_nonce(sw);

    // create and sign the content object
    cob = ccn_charbuf_create();
    if (cob == NULL) {
        res = -1;
        goto Cleanup;
    }
    if (slice != NULL) {
        content = ccn_charbuf_create();
        if (content == NULL) {
            res = -1;
            goto Cleanup;
        }
        res = append_slice(content, slice);
        if (res < 0)
            goto Cleanup;
        cbuf = content->buf;
        clength = content->length;
    } else {
        sparm.type = CCN_CONTENT_GONE;
    }

    sparm.sp_flags = CCN_SP_FINAL_BLOCK;
    res = ccn_sign_content(h, cob, name, &sparm, cbuf, clength);
    if (res < 0)
        goto Cleanup;
    // establish handler for interest in the slice content object
    wc = calloc(1, sizeof(*wc));
    if (wc == NULL) {
        res = -1;
        goto Cleanup;
    }
    wc->p = &write_interest_handler;
    wc->data = cob;
    res = ccn_set_interest_filter(h, name, wc);
    if (res < 0)
        goto Cleanup;
    templ = make_scope1_template();
    if (templ == NULL) {
        res = -1;
        goto Cleanup;
    }
    res = ccn_get(h, sw, templ, 1000, NULL, NULL, NULL, 0);
    if (res < 0)
        goto Cleanup;
    ccn_run(h, 1000); // give the repository a chance to fetch the data
    if (wc->intdata != 1) {
        res = -1;
        goto Cleanup;
    }
    res = 0;
Cleanup:
    ccn_set_interest_filter(h, name, NULL);
    if (wc != NULL)
        free(wc);
    ccn_charbuf_destroy(&cob);
    ccn_charbuf_destroy(&content);
    ccn_charbuf_destroy(&sw);
    ccn_charbuf_destroy(&templ);
    return (res);
}
Esempio n. 24
0
int
sign_content_with_user_defined_keystore(struct ccn_charbuf *content_name,
										struct ccn_charbuf *resultbuf,
										const void *data,
										size_t data_size,
										char *keystore_path,
										char *keystore_passphrase,
										char *key_repo_name,
										char *site_name,
										char *router_name){
	
	if ( nlsr->debugging )
		printf("sign_content_with_user_defined_keystore called\n");

	
	int res;


	struct ccn_charbuf * pubid_out=ccn_charbuf_create();
	struct ccn_charbuf * keyname;

	
	struct ccn_keystore *keystore = NULL;
	keystore=ccn_keystore_create();
	res=ccn_keystore_init(keystore, keystore_path,keystore_passphrase );
	if ( res < 0 ){
		if ( nlsr->debugging )
			printf("Error in initiating keystore :(\n");
		ccn_keystore_destroy(&keystore);
		return -1;
	}
	

	res=ccn_load_private_key	(nlsr->ccn,
							keystore_path,
							keystore_passphrase,
							pubid_out);

	if(res < 0 ){
		if ( nlsr->debugging )
			printf("Error in loading keystore :( \n");
		ccn_charbuf_destroy(&pubid_out);
		return -1;
	}

	char *baseuri=(char *)calloc(strlen(key_repo_name)+strlen(site_name)+
				  strlen(router_name)+strlen("/%C1.R.N.Start")+5,sizeof(char));
	memcpy(baseuri,key_repo_name,strlen(key_repo_name)+1);
	if ( site_name[0] != '/')
		memcpy(baseuri+strlen(baseuri),"/",1);
	memcpy(baseuri+strlen(baseuri),site_name,strlen(site_name)+1);
	memcpy(baseuri+strlen(baseuri),"/%C1.R.N.Start",strlen("/%C1.R.N.Start"));
	memcpy(baseuri+strlen(baseuri),router_name,strlen(router_name)+1);
	baseuri[strlen(baseuri)]='\0';
	

	keyname=ccn_charbuf_create();
	if(keyname == NULL ){
		ccn_charbuf_destroy(&pubid_out);
		free(baseuri);
		return -1;
	}
	ccn_name_from_uri(keyname,baseuri);
	if ( res < 0 ){
		if ( nlsr->debugging )
			printf("Bad URI format: %s\n",baseuri);
		ccn_charbuf_destroy(&pubid_out);
		ccn_charbuf_destroy(&keyname);
		free(baseuri);
		return -1;		
	}
	
	ccn_name_append_str(keyname,"nlsr");
	struct ccn_charbuf *keyid = ccn_charbuf_create();
	ccn_charbuf_append_value(keyid, CCN_MARKER_CONTROL, 1);
	ccn_charbuf_append_string(keyid, ".M.K");
	ccn_charbuf_append_value(keyid, 0, 1);
	ccn_charbuf_append_charbuf(keyid, pubid_out);
	ccn_name_append(keyname, keyid->buf, keyid->length);
	
	

	struct ccn_charbuf *uri = ccn_charbuf_create();
	ccn_uri_append(uri, keyname->buf, keyname->length, 0);
	if ( nlsr->debugging )
		printf("Key Name Included when processing content: %s\n", ccn_charbuf_as_string(uri));
	ccn_charbuf_destroy(&uri);	

	struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
	sp.type = CCN_CONTENT_DATA;
 	sp.template_ccnb = ccn_charbuf_create();
  	ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
	ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyLocator, CCN_DTAG);
  	ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyName, CCN_DTAG);
  	ccn_charbuf_append(sp.template_ccnb, keyname->buf, keyname->length); 
	ccn_charbuf_append_closer(sp.template_ccnb); // KeyName closer
  	ccn_charbuf_append_closer(sp.template_ccnb); // KeyLocator closer
  	ccn_charbuf_append_closer(sp.template_ccnb); // SignedInfo closer
	
	sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR;
	sp.sp_flags |= CCN_SP_FINAL_BLOCK;
	sp.freshness = 60;


	if (pubid_out->length != sizeof(sp.pubid)){
		if ( nlsr->debugging )
			printf("Size of pubid and sp.pubid is not equal");
		ccn_charbuf_destroy(&keyname);
		ccn_charbuf_destroy(&pubid_out);
		free(baseuri);
		return -1;
	}
	
	memcpy(sp.pubid, pubid_out->buf, pubid_out->length);
	


	res=ccn_sign_content(nlsr->ccn,resultbuf,content_name,&sp,data,data_size);
	if( res < 0 ){
		if ( nlsr->debugging )
			printf("Content signing error \n");
		ccn_charbuf_destroy(&sp.template_ccnb);
		ccn_charbuf_destroy(&keyid);
		ccn_charbuf_destroy(&keyname);
		ccn_charbuf_destroy(&pubid_out);
		free(baseuri);
 		return -1;
	}

	ccn_charbuf_destroy(&sp.template_ccnb);
	ccn_charbuf_destroy(&keyid);
	ccn_charbuf_destroy(&keyname);
	ccn_charbuf_destroy(&pubid_out);
	free(baseuri);
 	return 0;
}
Esempio n. 25
0
static PyObject *
Interest_obj_to_ccn(PyObject *py_obj_Interest)
{
	struct ccn_charbuf *interest;
	PyObject *py_interest, *py_o;
	int r;

	py_interest = CCNObject_New_charbuf(INTEREST, &interest);
	if (!py_interest)
		return NULL;

	r = ccn_charbuf_append_tt(interest, CCN_DTAG_Interest, CCN_DTAG);
	JUMP_IF_NEG_MEM(r, error);

	/* Name */
	{
		struct ccn_charbuf *name;
		PyObject *py_name;

		r = is_attr_set(py_obj_Interest, "name", &py_o);
		JUMP_IF_NEG(r, error);

		if (r) {
			py_name = Name_obj_to_ccn(py_o);
			Py_DECREF(py_o);
			JUMP_IF_NULL(py_name, error);
			name = CCNObject_Get(NAME, py_name);

			r = ccn_charbuf_append_charbuf(interest, name);
			Py_DECREF(py_name);
			JUMP_IF_NEG_MEM(r, error);
		} else {
			// Even though Name is mandatory we still use this code to generate
			// templates, so it is ok if name is not given, the code below
			// creates an empty tag
			r = ccn_charbuf_append_tt(interest, CCN_DTAG_Name, CCN_DTAG);
			JUMP_IF_NEG(r, error);

			r = ccn_charbuf_append_closer(interest); /* </Name> */
			JUMP_IF_NEG(r, error);
		}
	}

	r = process_int_attribute(interest, CCN_DTAG_MinSuffixComponents,
			py_obj_Interest, "minSuffixComponents");
	JUMP_IF_NEG(r, error);

	r = process_int_attribute(interest, CCN_DTAG_MaxSuffixComponents,
			py_obj_Interest, "maxSuffixComponents");
	JUMP_IF_NEG(r, error);

	r = is_attr_set(py_obj_Interest, "publisherPublicKeyDigest", &py_o);
	JUMP_IF_NEG(r, error);
	if (r) {
		const char *blob;
		Py_ssize_t blobsize;

		blob = PyBytes_AsString(py_o);
		if (!blob) {
			Py_DECREF(py_o);
			goto error;
		}
		blobsize = PyBytes_GET_SIZE(py_o);

		r = ccnb_append_tagged_blob(interest, CCN_DTAG_PublisherPublicKeyDigest,
				blob, blobsize);
		Py_DECREF(py_o);
		JUMP_IF_NEG_MEM(r, error);
	}

	r = is_attr_set(py_obj_Interest, "exclude", &py_o);
	JUMP_IF_NEG(r, error);
	if (r) {
		PyObject *py_exclusions;
		struct ccn_charbuf *exclusion_filter;

		if (!PyObject_IsInstance(py_o, g_type_ExclusionFilter)) {
			Py_DECREF(py_o);
			PyErr_SetString(PyExc_TypeError, "Expected ExclusionFilter");
			goto error;
		}

		r = is_attr_set(py_o, "ccn_data", &py_exclusions);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);

		exclusion_filter = CCNObject_Get(EXCLUSION_FILTER, py_exclusions);
		r = ccn_charbuf_append_charbuf(interest, exclusion_filter);
		Py_DECREF(py_exclusions);
		JUMP_IF_NEG(r, error);
	}

	r = process_int_attribute(interest, CCN_DTAG_ChildSelector,
			py_obj_Interest, "childSelector");
	JUMP_IF_NEG(r, error);

	r = process_int_attribute(interest, CCN_DTAG_AnswerOriginKind,
			py_obj_Interest, "answerOriginKind");
	JUMP_IF_NEG(r, error);

	r = process_int_attribute(interest, CCN_DTAG_Scope, py_obj_Interest,
			"scope");
	JUMP_IF_NEG(r, error);

	r = is_attr_set(py_obj_Interest, "interestLifetime", &py_o);
	if (r) {
		unsigned char buf[3] = {0};
		double lifetime;
		unsigned long i_lifetime;

		if (!PyFloat_Check(py_o)) {
			Py_DECREF(py_o);
			PyErr_SetString(PyExc_TypeError, "expected float type in interest"
					" lifetime");
			goto error;
		}

		lifetime = PyFloat_AS_DOUBLE(py_o);
		Py_DECREF(py_o);

		i_lifetime = lifetime * 4096;

		/* XXX: probably won't work in bigendian */
		for (int i = sizeof(buf) - 1; i >= 0; i--, i_lifetime >>= 8)
			buf[i] = i_lifetime & 0xff;

		r = ccnb_append_tagged_blob(interest, CCN_DTAG_InterestLifetime,
				buf, sizeof(buf));
		JUMP_IF_NEG_MEM(r, error);
	}

	r = is_attr_set(py_obj_Interest, "nonce", &py_o);
	if (r) {
		char *s;
		Py_ssize_t len;

		r = PyBytes_AsStringAndSize(py_o, &s, &len);
		if (r < 0) {
			Py_DECREF(py_o);
			goto error;
		}

		r = ccnb_append_tagged_blob(interest, CCN_DTAG_Nonce, s, len);
		Py_DECREF(py_o);
		JUMP_IF_NEG_MEM(r, error);
	}

	r = ccn_charbuf_append_closer(interest); /* </Interest> */
	JUMP_IF_NEG_MEM(r, error);

	return py_interest;

error:
	Py_DECREF(py_interest);

	return NULL;
}
Esempio n. 26
0
/**
 * Create SignedInfo.
 *
 *
 * @param c is used to hold the result.
 * @param publisher_key_id points to the digest of the publisher key id.
 * @param publisher_key_id_size is the size in bytes(32) of the pub key digest
 * @param timestamp holds the timestamp, as a ccnb-encoded blob, or is NULL
          to use the current time.
 * @param type indicates the Type of the ContentObject.
 * @param freshness is the FreshnessSeconds value, or -1 to omit.
 * @param finalblockid holds the FinalBlockID, as a ccnb-encoded blob, or is
          NULL to omit.
 * @param key_locator is the ccnb-encoded KeyLocator element, or NULL to omit.
 * @returns 0 for success or -1 for error.
 */
int
ccn_signed_info_create(struct ccn_charbuf *c,
                       const void *publisher_key_id,	/* input, sha256 hash */
                       size_t publisher_key_id_size, 	/* input, 32 for sha256 hashes */
                       const struct ccn_charbuf *timestamp,/* input ccnb blob, NULL for "now" */
                       enum ccn_content_type type,	/* input */
                       int freshness,			/* input, -1 means omit */
                       const struct ccn_charbuf *finalblockid,  /* input, NULL means omit */
                       const struct ccn_charbuf *key_locator)	/* input, optional, ccnb encoded */
{
    int res = 0;
    const char fakepubkeyid[32] = {0};
 
    if (publisher_key_id != NULL && publisher_key_id_size != 32)
        return(-1);

    res |= ccn_charbuf_append_tt(c, CCN_DTAG_SignedInfo, CCN_DTAG);

    res |= ccn_charbuf_append_tt(c, CCN_DTAG_PublisherPublicKeyDigest, CCN_DTAG);
    if (publisher_key_id != NULL) {
        res |= ccn_charbuf_append_tt(c, publisher_key_id_size, CCN_BLOB);
        res |= ccn_charbuf_append(c, publisher_key_id, publisher_key_id_size);
    } else {
        /* XXX - obtain the default publisher key id and append it */
        res |= ccn_charbuf_append_tt(c, sizeof(fakepubkeyid), CCN_BLOB);
        res |= ccn_charbuf_append(c, fakepubkeyid, sizeof(fakepubkeyid));
    }
    res |= ccn_charbuf_append_closer(c);

    res |= ccn_charbuf_append_tt(c, CCN_DTAG_Timestamp, CCN_DTAG);
    if (timestamp != NULL)
        res |= ccn_charbuf_append_charbuf(c, timestamp);
    else
        res |= ccnb_append_now_blob(c, CCN_MARKER_NONE);
    res |= ccn_charbuf_append_closer(c);

    if (type != CCN_CONTENT_DATA) {
        res |= ccn_charbuf_append_tt(c, CCN_DTAG_Type, CCN_DTAG);
        res |= ccn_charbuf_append_tt(c, 3, CCN_BLOB);
        res |= ccn_charbuf_append_value(c, type, 3);
        res |= ccn_charbuf_append_closer(c);
    }

    if (freshness >= 0)
        res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d", freshness);

    if (finalblockid != NULL) {
        res |= ccn_charbuf_append_tt(c, CCN_DTAG_FinalBlockID, CCN_DTAG);
        res |= ccn_charbuf_append_charbuf(c, finalblockid);
        res |= ccn_charbuf_append_closer(c);
    }

    if (key_locator != NULL) {
	/* key_locator is a sub-type that should already be encoded */
	res |= ccn_charbuf_append_charbuf(c, key_locator);
    }
    
    res |= ccn_charbuf_append_closer(c);

    return(res == 0 ? 0 : -1);
}
Esempio n. 27
0
/**
 * Creates a stream for a named interest.
 * The name should be a ccnb encoded interest.
 * If resolveVersion, then we assume that the version is unresolved, 
 * and an attempt is made to determine the version number using the highest
 * version.
 * The number of buffers (nBufs) may be silently limited.
 * @returns NULL if the stream creation failed,
 * otherwise returns the new stream.
 */
extern struct ccn_fetch_stream *
ccn_fetch_open(struct ccn_fetch *f,
			   struct ccn_charbuf *name,
			   const char *id,
			   struct ccn_charbuf *interestTemplate,
			   int maxBufs,
			   int resolveVersion,
			   int assumeFixed) {
	// returns a new ccn_fetch_stream object based on the arguments
	// returns NULL if not successful
    if (maxBufs <= 0) return NULL;
	if (maxBufs > 16) maxBufs = 16;
	int res = 0;
	FILE *debug = f->debug;
	ccn_fetch_flags flags = f->debugFlags;
    
	// first, resolve the version
	struct ccn_fetch_stream *fs = calloc(1, sizeof(*fs));
	fs->segSize = (assumeFixed ? 0 : -1);
	fs->name = ccn_charbuf_create();
	fs->id = newStringCopy(id);
	ccn_charbuf_append_charbuf(fs->name, name);
	if (resolveVersion) {
		int tmInc = 40; // TBD: need better strategy for version timeout
		int tm = 0;
		while (tm < CCN_VERSION_TIMEOUT) {
			res = ccn_resolve_version(f->h, fs->name, resolveVersion, tmInc);
			if (res >= 0) break;
			tm = tm + tmInc;
		}
		if (res < 0) {
			// could not resolve version for this name
			// get rid of allocations so far and bail out
			if (debug != NULL && (flags & ccn_fetch_flags_NoteOpenClose)) {
				fprintf(debug, 
						"-- ccn_fetch open, %s, failed to resolve version\n",
						fs->id);
				fflush(debug);
			}
			ccn_charbuf_destroy(&fs->name);
			freeString(fs->id);
			free(fs);
			return NULL;
		}
	}
	fs->maxBufs = maxBufs;
	fs->segsAhead = 0;
	fs->fileSize = -1;
	fs->finalSeg = -1;
	fs->timeoutSeg = -1;
	fs->zeroLenSeg = -1;
	fs->parent = f;
	fs->timeoutUSecs = CCN_INTEREST_TIMEOUT_USECS;  // TBD: how to get better timeout?
	
	// use the supplied template or the default
	if (interestTemplate != NULL) {
		struct ccn_charbuf *cb = ccn_charbuf_create();
		ccn_charbuf_append_charbuf(cb, interestTemplate);
		fs->interest = cb;
	} else
		fs->interest = make_data_template(MaxSuffixDefault);
	
	
	// remember the stream in the parent
	int ns = f->nStreams;
	int max = f->maxStreams;
	if (ns >= max) {
		// extend the vector
		int nMax = max+max/2+4;
        f->streams = realloc(f->streams, sizeof(*(f->streams)) * nMax);
		f->maxStreams = nMax;
	}
	// guaranteed room to add at the end
	f->streams[ns] = fs;
	f->nStreams = ns+1;
	
	if (debug != NULL && (flags & ccn_fetch_flags_NoteOpenClose)) {
		fprintf(debug, 
				"-- ccn_fetch open, %s\n",
				fs->id);
		fflush(debug);
	}
	// prep for the first segment
	NeedSegment(fs, 0);
	return fs;
}