struct ccn_parsed_interest * _pyccn_interest_get_pi(PyObject *py_interest) { struct interest_data *context; struct ccn_charbuf *interest; int r; assert(CCNObject_IsValid(INTEREST, py_interest)); context = PyCapsule_GetContext(py_interest); assert(context); if (context->pi) return context->pi; interest = CCNObject_Get(INTEREST, py_interest); context->pi = calloc(1, sizeof(struct ccn_parsed_interest)); JUMP_IF_NULL_MEM(context->pi, error); /* TODO: we should also use the comps argument */ r = ccn_parse_interest(interest->buf, interest->length, context->pi, NULL); if (r < 0) { PyErr_SetString(g_PyExc_CCNInterestError, "Unable to parse the" " Interest"); goto error; } assert(context->pi); return context->pi; error: return NULL; }
PyObject * _pyccn_cmd_verify_signature(PyObject *UNUSED(self), PyObject *args) { PyObject *py_content_object, *py_pub_key; PyObject *res; struct ccn_charbuf *content_object; struct ccn_parsed_ContentObject *pco; struct ccn_pkey *pub_key; int r; if (!PyArg_ParseTuple(args, "OO", &py_content_object, &py_pub_key)) return NULL; if (!CCNObject_IsValid(CONTENT_OBJECT, py_content_object)) { PyErr_SetString(PyExc_TypeError, "argument 1 must be CCN" " ContentObject"); return NULL; } if (!CCNObject_IsValid(PKEY_PUB, py_pub_key)) { PyErr_SetString(PyExc_TypeError, "argument 2 must be CCN public key"); return NULL; } content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object); pco = _pyccn_content_object_get_pco(py_content_object); if (!pco) return NULL; pub_key = CCNObject_Get(PKEY_PUB, py_pub_key); r = ccn_verify_signature(content_object->buf, content_object->length, pco, pub_key); if (r < 0) { PyErr_SetString(g_PyExc_CCNSignatureError, "error verifying signature"); return NULL; } res = r ? Py_True : Py_False; return Py_INCREF(res), res; }
PyObject * _pyccn_cmd_content_matches_interest(PyObject *UNUSED(self), PyObject *args) { PyObject *py_content_object, *py_interest; struct ccn_charbuf *content_object, *interest; struct ccn_parsed_ContentObject *pco; struct ccn_parsed_interest *pi; int r; PyObject *res; if (!PyArg_ParseTuple(args, "OO", &py_content_object, &py_interest)) return NULL; if (!CCNObject_IsValid(CONTENT_OBJECT, py_content_object)) { PyErr_SetString(PyExc_TypeError, "Expected CCN ContentObject"); return NULL; } if (!CCNObject_IsValid(INTEREST, py_interest)) { PyErr_SetString(PyExc_TypeError, "Expected CCN Interest"); return NULL; } content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object); interest = CCNObject_Get(INTEREST, py_interest); pco = _pyccn_content_object_get_pco(py_content_object); if (!pco) return NULL; pi = _pyccn_interest_get_pi(py_interest); if (!pi) return NULL; r = ccn_content_matches_interest(content_object->buf, content_object->length, 1, pco, interest->buf, interest->length, pi); res = r ? Py_True : Py_False; return Py_INCREF(res), res; }
PyObject * _pyccn_cmd_verify_content(PyObject *UNUSED(self), PyObject *args) { PyObject *py_handle, *py_content_object; PyObject *res; struct ccn *handle; struct ccn_charbuf *content_object; struct ccn_parsed_ContentObject *pco; int r; if (!PyArg_ParseTuple(args, "OO", &py_handle, &py_content_object)) return NULL; if (!CCNObject_IsValid(HANDLE, py_handle)) { PyErr_SetString(PyExc_TypeError, "argument 1 must be a CCN handle"); return NULL; } if (!CCNObject_IsValid(CONTENT_OBJECT, py_content_object)) { PyErr_SetString(PyExc_TypeError, "argument 2 must be CCN" " ContentObject"); return NULL; } handle = CCNObject_Get(HANDLE, py_handle); content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object); pco = _pyccn_content_object_get_pco(py_content_object); if (!pco) return NULL; assert(content_object->length == pco->offset[CCN_PCO_E]); r = ccn_verify_content(handle, content_object->buf, pco); res = r == 0 ? Py_True : Py_False; return Py_INCREF(res), res; }
static PyObject * Name_obj_from_ccn_parsed(PyObject *py_content_object) { struct ccn_charbuf *content_object; struct ccn_parsed_ContentObject *parsed_content_object; PyObject *py_ccn_name; PyObject *py_Name; struct ccn_charbuf *name; size_t name_begin, name_end, s; int r; assert(CCNObject_IsValid(CONTENT_OBJECT, py_content_object)); content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object); parsed_content_object = _pyccn_content_object_get_pco(py_content_object); if (!parsed_content_object) return NULL; name_begin = parsed_content_object->offset[CCN_PCO_B_Name]; name_end = parsed_content_object->offset[CCN_PCO_E_Name]; s = name_end - name_begin; debug("ContentObject_from_ccn_parsed Name len=%zd\n", s); if (parsed_content_object->name_ncomps <= 0) { PyErr_SetString(g_PyExc_CCNNameError, "No name stored (or name is" " invalid) in parsed content object"); return NULL; } py_ccn_name = CCNObject_New_charbuf(NAME, &name); if (!py_ccn_name) return NULL; r = ccn_charbuf_append(name, &content_object->buf[name_begin], s); if (r < 0) { Py_DECREF(py_ccn_name); return PyErr_NoMemory(); } #if DEBUG_MSG debug("Name: "); dump_charbuf(name, stderr); debug("\n"); #endif py_Name = Name_obj_from_ccn(py_ccn_name); Py_DECREF(py_ccn_name); return py_Name; }
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; }
PyObject * _pyccn_cmd_digest_contentobject(PyObject *UNUSED(self), PyObject *args) { PyObject *py_content_object; struct ccn_charbuf *content_object; struct ccn_parsed_ContentObject *parsed_content_object; PyObject *py_digest; if (!PyArg_ParseTuple(args, "O", &py_content_object)) return NULL; if (!CCNObject_IsValid(CONTENT_OBJECT, py_content_object)) { PyErr_SetString(PyExc_TypeError, "Expected CCN ContentObject"); return NULL; } content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object); parsed_content_object = _pyccn_content_object_get_pco(py_content_object); if (!parsed_content_object) return NULL; /* * sanity check (sigh, I guess pco and comps should be carried in * capsule's context, since they're very closely related) */ if (content_object->length != parsed_content_object->offset[CCN_PCO_E]) { PyErr_SetString(PyExc_ValueError, "ContentObject size doesn't match" " the size reported by pco"); return NULL; } ccn_digest_ContentObject(content_object->buf, parsed_content_object); py_digest = PyBytes_FromStringAndSize( (char *) parsed_content_object->digest, parsed_content_object->digest_bytes); return py_digest; }
PyObject * Signature_obj_from_ccn(PyObject *py_signature) { struct ccn_charbuf *signature; PyObject *py_obj_signature, *py_o; struct ccn_buf_decoder decoder, *d; size_t start, stop, size; const unsigned char *ptr; int r; assert(CCNObject_IsValid(SIGNATURE, py_signature)); signature = CCNObject_Get(SIGNATURE, py_signature); debug("Signature_from_ccn start, len=%zd\n", signature->length); // 1) Create python object py_obj_signature = PyObject_CallObject(g_type_Signature, NULL); if (!py_obj_signature) return NULL; // 2) Set ccn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. r = PyObject_SetAttrString(py_obj_signature, "ccn_data", py_signature); JUMP_IF_NEG(r, error); // 3) Parse c structure and fill python attributes // Neither DigestAlgorithm nor Witness are included in the packet // from ccnput, so they are apparently both optional d = ccn_buf_decoder_start(&decoder, signature->buf, signature->length); if (!ccn_buf_match_dtag(d, CCN_DTAG_Signature)) { PyErr_Format(g_PyExc_CCNSignatureError, "Error finding" " CCN_DTAG_Signature (decoder state: %d)", d->decoder.state); goto error; } debug("Is a signature\n"); ccn_buf_advance(d); /* CCN_DTAG_DigestAlgorithm */ start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_DigestAlgorithm, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, d->buf, start, stop, &ptr, &size); if (r == 0) { debug("PyObject_SetAttrString digestAlgorithm\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_signature, "digestAlgorithm", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* CCN_DTAG_Witness */ start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Witness, 1, -1); stop = d->decoder.token_index; debug("witness start %zd stop %zd\n", start, stop); r = ccn_ref_tagged_BLOB(CCN_DTAG_Witness, d->buf, start, stop, &ptr, &size); if (r == 0) { // The Witness is represented as a DER-encoded PKCS#1 DigestInfo, // which contains an AlgorithmIdentifier (an OID, together with any necessary parameters) // and a byte array (OCTET STRING) containing the digest information to be interpreted according to that OID. // http://www.ccnx.org/releases/latest/doc/technical/SignatureGeneration.html debug("PyObject_SetAttrString witness\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_signature, "witness", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* CCN_DTAG_SignatureBits */ start = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SignatureBits, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, d->buf, start, stop, &ptr, &size); if (r < 0) { PyErr_Format(g_PyExc_CCNSignatureError, "Error parsing" " CCN_DTAG_SignatureBits (decoder state %d)", d->decoder.state); goto error; } assert(r == 0); debug("PyObject_SetAttrString signatureBits\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_signature, "signatureBits", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); ccn_buf_check_close(d); if (d->decoder.state < 0) { PyErr_Format(g_PyExc_CCNSignatureError, "Signature decoding error" " (decoder state: %d, numval: %zd)", d->decoder.state, d->decoder.numval); goto error; } // 4) Return the created object debug("Signature_from_ccn ends\n"); return py_obj_signature; error: Py_DECREF(py_obj_signature); return NULL; }
PyObject * _pyccn_cmd_encode_ContentObject(PyObject *UNUSED(self), PyObject *args) { PyObject *py_content_object, *py_name, *py_content, *py_signed_info, *py_key; PyObject *py_o = NULL, *ret = NULL; struct ccn_charbuf *name, *signed_info, *content_object = NULL; struct ccn_pkey *private_key; const char *digest_alg = NULL; char *content; Py_ssize_t content_len; int r; if (!PyArg_ParseTuple(args, "OOOOO", &py_content_object, &py_name, &py_content, &py_signed_info, &py_key)) return NULL; if (strcmp(py_content_object->ob_type->tp_name, "ContentObject")) { PyErr_SetString(PyExc_TypeError, "Must pass a ContentObject as arg 1"); return NULL; } if (!CCNObject_IsValid(NAME, py_name)) { PyErr_SetString(PyExc_TypeError, "Must pass a CCN Name as arg 2"); return NULL; } else name = CCNObject_Get(NAME, py_name); if (py_content != Py_None && !PyBytes_Check(py_content)) { PyErr_SetString(PyExc_TypeError, "Must pass a Bytes as arg 3"); return NULL; } else if (py_content == Py_None) { content = NULL; content_len = 0; } else { r = PyBytes_AsStringAndSize(py_content, &content, &content_len); if (r < 0) return NULL; } if (!CCNObject_IsValid(SIGNED_INFO, py_signed_info)) { PyErr_SetString(PyExc_TypeError, "Must pass a CCN SignedInfo as arg 4"); return NULL; } else signed_info = CCNObject_Get(SIGNED_INFO, py_signed_info); if (strcmp(py_key->ob_type->tp_name, "Key")) { PyErr_SetString(PyExc_TypeError, "Must pass a Key as arg 4"); return NULL; } // DigestAlgorithm py_o = PyObject_GetAttrString(py_content_object, "digestAlgorithm"); if (py_o != Py_None) { PyErr_SetString(PyExc_NotImplementedError, "non-default digest" " algorithm not yet supported"); goto error; } Py_CLEAR(py_o); // Key private_key = Key_to_ccn_private(py_key); // Note that we don't load this key into the keystore hashtable in the library // because it makes this method require access to a ccn handle, and in fact, // ccn_sign_content just uses what's in signedinfo (after an error check by // chk_signing_params and then calls ccn_encode_ContentObject anyway // // Encode the content object // Build the ContentObject here. content_object = ccn_charbuf_create(); JUMP_IF_NULL_MEM(content_object, error); r = ccn_encode_ContentObject(content_object, name, signed_info, content, content_len, digest_alg, private_key); debug("ccn_encode_ContentObject res=%d\n", r); if (r < 0) { ccn_charbuf_destroy(&content_object); PyErr_SetString(g_PyExc_CCNError, "Unable to encode ContentObject"); goto error; } ret = CCNObject_New(CONTENT_OBJECT, content_object); error: Py_XDECREF(py_o); return ret; }
PyObject * ContentObject_obj_from_ccn(PyObject *py_content_object) { struct ccn_charbuf *content_object; struct ccn_parsed_ContentObject *parsed_content_object; PyObject *py_obj_ContentObject, *py_o; int r; struct ccn_charbuf *signature; PyObject *py_signature; struct ccn_charbuf *signed_info; PyObject *py_signed_info; if (!CCNObject_ReqType(CONTENT_OBJECT, py_content_object)) return NULL; content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object); parsed_content_object = _pyccn_content_object_get_pco(py_content_object); if (!parsed_content_object) return NULL; debug("ContentObject_from_ccn_parsed content_object->length=%zd\n", content_object->length); py_obj_ContentObject = PyObject_CallObject(g_type_ContentObject, NULL); if (!py_obj_ContentObject) return NULL; /* Name */ py_o = Name_obj_from_ccn_parsed(py_content_object); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_ContentObject, "name", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); /* Content */ py_o = Content_from_ccn_parsed(content_object, parsed_content_object); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_ContentObject, "content", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); /* Signature */ debug("ContentObject_from_ccn_parsed Signature\n"); py_signature = CCNObject_New_charbuf(SIGNATURE, &signature); JUMP_IF_NULL(py_signature, error); r = ccn_charbuf_append(signature, &content_object->buf[parsed_content_object->offset[CCN_PCO_B_Signature]], (size_t) (parsed_content_object->offset[CCN_PCO_E_Signature] - parsed_content_object->offset[CCN_PCO_B_Signature])); if (r < 0) { PyErr_NoMemory(); Py_DECREF(py_signature); goto error; } py_o = Signature_obj_from_ccn(py_signature); Py_DECREF(py_signature); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_ContentObject, "signature", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); debug("ContentObject_from_ccn_parsed SignedInfo\n"); py_signed_info = CCNObject_New_charbuf(SIGNED_INFO, &signed_info); JUMP_IF_NULL(py_signed_info, error); r = ccn_charbuf_append(signed_info, &content_object->buf[parsed_content_object->offset[CCN_PCO_B_SignedInfo]], (size_t) (parsed_content_object->offset[CCN_PCO_E_SignedInfo] - parsed_content_object->offset[CCN_PCO_B_SignedInfo])); if (r < 0) { PyErr_NoMemory(); Py_DECREF(py_signed_info); goto error; } py_o = SignedInfo_obj_from_ccn(py_signed_info); Py_DECREF(py_signed_info); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_ContentObject, "signedInfo", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); debug("ContentObject_from_ccn_parsed DigestAlgorithm\n"); // TODO... Note this seems to default to nothing in the library...? r = PyObject_SetAttrString(py_obj_ContentObject, "digestAlgorithm", Py_None); JUMP_IF_NEG(r, error); /* Original data */ debug("ContentObject_from_ccn_parsed ccn_data\n"); r = PyObject_SetAttrString(py_obj_ContentObject, "ccn_data", py_content_object); JUMP_IF_NEG(r, error); r = PyObject_SetAttrString(py_obj_ContentObject, "ccn_data_dirty", Py_False); JUMP_IF_NEG(r, error); debug("ContentObject_from_ccn_parsed complete\n"); return py_obj_ContentObject; error: Py_XDECREF(py_obj_ContentObject); return NULL; }
PyObject * Interest_obj_from_ccn(PyObject *py_interest) { struct ccn_charbuf *interest; struct ccn_parsed_interest *pi; PyObject *py_obj_Interest, *py_o; int r; debug("Interest_from_ccn_parsed start\n"); interest = CCNObject_Get(INTEREST, py_interest); // 1) Create python object py_obj_Interest = PyObject_CallObject(g_type_Interest, NULL); if (!py_obj_Interest) return NULL; pi = _pyccn_interest_get_pi(py_interest); JUMP_IF_NULL(pi, error); // 2) Set ccn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. r = PyObject_SetAttrString(py_obj_Interest, "ccn_data", py_interest); JUMP_IF_NEG(r, error); // 3) Parse c structure and fill python attributes // using PyObject_SetAttrString ssize_t len; const unsigned char *blob; size_t blob_size, start, end; struct ccn_charbuf * cb; // Best decoding examples are in packet-ccn.c for wireshark plugin? // self.name = None # Start from None to use for templates? len = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name]; if (len > 0) { PyObject *py_cname; py_cname = CCNObject_New_charbuf(NAME, &cb); JUMP_IF_NULL(py_cname, error); r = ccn_charbuf_append(cb, interest->buf + pi->offset[CCN_PI_B_Name], len); JUMP_IF_NEG_MEM(r, error); py_o = Name_obj_from_ccn(py_cname); Py_DECREF(py_cname); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "name", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } else { PyErr_SetString(g_PyExc_CCNInterestError, "Got interest without a" " name!"); goto error; } // self.minSuffixComponents = None # default 0 len = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents]; if (len > 0) { r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_MinSuffixComponents, interest->buf, pi->offset[CCN_PI_B_MinSuffixComponents], pi->offset[CCN_PI_E_MinSuffixComponents]); if (r < 0) { PyErr_SetString(g_PyExc_CCNInterestError, "Invalid" " MinSuffixComponents value"); goto error; } py_o = _pyccn_Int_FromLong(r); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "minSuffixComponents", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } // self.maxSuffixComponents = None # default infinity len = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents]; if (len > 0) { r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_MaxSuffixComponents, interest->buf, pi->offset[CCN_PI_B_MaxSuffixComponents], pi->offset[CCN_PI_E_MaxSuffixComponents]); if (r < 0) { PyErr_SetString(g_PyExc_CCNInterestError, "Invalid" " MaxSuffixComponents value"); goto error; } py_o = _pyccn_Int_FromLong(r); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "maxSuffixComponents", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } // self.publisherPublicKeyDigest = None # SHA256 hash // TODO: what is CN_PI_B_PublisherID? -- looks like it is the data including // the tags while PublisherIDKeyDigest // is just the raw digest -- dk start = pi->offset[CCN_PI_B_PublisherID]; end = pi->offset[CCN_PI_E_PublisherID]; len = end - start; if (len > 0) { r = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, interest->buf, start, end, &blob, &blob_size); if (r < 0) { PyErr_SetString(g_PyExc_CCNInterestError, "Invalid" " PublisherPublicKeyDigest value"); goto error; } py_o = PyBytes_FromStringAndSize((const char*) blob, blob_size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "publisherPublicKeyDigest", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } // self.exclude = None len = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]; if (len > 0) { PyObject *py_exclusion_filter; py_exclusion_filter = CCNObject_New_charbuf(EXCLUSION_FILTER, &cb); JUMP_IF_NULL(py_exclusion_filter, error); r = ccn_charbuf_append(cb, interest->buf + pi->offset[CCN_PI_B_Exclude], len); JUMP_IF_NEG_MEM(r, error); py_o = ExclusionFilter_obj_from_ccn(py_exclusion_filter); Py_DECREF(py_exclusion_filter); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "exclude", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } // self.childSelector = None len = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector]; if (len > 0) { r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_ChildSelector, interest->buf, pi->offset[CCN_PI_B_ChildSelector], pi->offset[CCN_PI_E_ChildSelector]); if (r < 0) { PyErr_SetString(g_PyExc_CCNInterestError, "Invalid" " ChildSelector value"); goto error; } py_o = _pyccn_Int_FromLong(r); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "childSelector", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } // self.answerOriginKind = None len = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind]; if (len > 0) { r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_AnswerOriginKind, interest->buf, pi->offset[CCN_PI_B_AnswerOriginKind], pi->offset[CCN_PI_E_AnswerOriginKind]); if (r < 0) { PyErr_SetString(g_PyExc_CCNInterestError, "Invalid" " AnswerOriginKind value"); goto error; } py_o = _pyccn_Int_FromLong(r); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "answerOriginKind", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } // self.scope = None len = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope]; if (len > 0) { r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_Scope, interest->buf, pi->offset[CCN_PI_B_Scope], pi->offset[CCN_PI_E_Scope]); if (r < 0) { PyErr_SetString(g_PyExc_CCNInterestError, "Invalid" " Scope value"); goto error; } py_o = _pyccn_Int_FromLong(r); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "scope", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } // self.interestLifetime = None len = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime]; if (len > 0) { double lifetime; // From packet-ccn.c r = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, interest->buf, pi->offset[CCN_PI_B_InterestLifetime], pi->offset[CCN_PI_E_InterestLifetime], &blob, &blob_size); if (r < 0) { PyErr_SetString(g_PyExc_CCNInterestError, "Invalid" " InterestLifetime value"); goto error; } /* XXX: probably won't work with bigendian */ lifetime = 0.0; for (size_t i = 0; i < blob_size; i++) lifetime = lifetime * 256.0 + (double) blob[i]; lifetime /= 4096.0; py_o = PyFloat_FromDouble(lifetime); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "interestLifetime", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } // self.nonce = None len = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce]; if (len > 0) { r = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, interest->buf, pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob, &blob_size); if (r < 0) { PyErr_SetString(g_PyExc_CCNInterestError, "Invalid" " Nonce value"); goto error; } py_o = PyBytes_FromStringAndSize((const char *) blob, blob_size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Interest, "nonce", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } r = PyObject_SetAttrString(py_obj_Interest, "ccn_data_dirty", Py_False); JUMP_IF_NEG(r, error); // 4) Return the created object debug("Interest_from_ccn ends\n"); return py_obj_Interest; error: Py_DECREF(py_obj_Interest); return NULL; }
static PyObject * ExclusionFilter_names_to_ccn(PyObject *py_obj_Names) { PyObject *py_iterator = NULL, *py_item = NULL; PyObject *py_exclude, *py_o; struct ccn_charbuf *exclude, *name; int r; // Build exclusion list - This uses explicit exclusion rather than // Bloom filters as Bloom will be deprecated // IMPORTANT: Exclusion component list must be sorted following // "Canonical CCNx ordering" // http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html // in which shortest components go first. // This sorting is expected to be handled on the Python side, not here. assert(py_obj_Names); py_exclude = CCNObject_New_charbuf(EXCLUSION_FILTER, &exclude); JUMP_IF_NULL(py_exclude, error); if (py_obj_Names == Py_None) return py_exclude; r = ccn_charbuf_append_tt(exclude, CCN_DTAG_Exclude, CCN_DTAG); JUMP_IF_NEG_MEM(r, error); // This code is similar to what's used in Name; // could probably be generalized. py_iterator = PyObject_GetIter(py_obj_Names); JUMP_IF_NULL(py_iterator, error); while ((py_item = PyIter_Next(py_iterator))) { int type; if (!PyObject_IsInstance(py_item, g_type_Name)) { PyErr_SetString(PyExc_ValueError, "Expected Name element"); goto error; } py_o = PyObject_GetAttrString(py_item, "type"); JUMP_IF_NULL(py_o, error); type = PyLong_AsLong(py_o); Py_DECREF(py_o); JUMP_IF_ERR(error); if (type == 0) { py_o = PyObject_GetAttrString(py_item, "ccn_data"); JUMP_IF_NULL(py_o, error); if (!CCNObject_IsValid(NAME, py_o)) { Py_DECREF(py_o); PyErr_SetString(PyExc_TypeError, "Expected CCN Name"); goto error; } name = CCNObject_Get(NAME, py_o); /* append without CCN name tag */ assert(name->length >= 4); r = ccn_charbuf_append(exclude, name->buf + 1, name->length - 2); Py_DECREF(py_o); JUMP_IF_NEG_MEM(r, error); } else if (type == 1) { r = ccn_charbuf_append_tt(exclude, CCN_DTAG_Any, CCN_DTAG); JUMP_IF_NEG_MEM(r, error); r = ccn_charbuf_append_closer(exclude); JUMP_IF_NEG_MEM(r, error); } else { PyErr_SetString(PyExc_ValueError, "Unhandled Name type"); goto error; } Py_CLEAR(py_item); } Py_CLEAR(py_iterator); r = ccn_charbuf_append_closer(exclude); /* </Exclude> */ JUMP_IF_NEG_MEM(r, error); return py_exclude; error: Py_XDECREF(py_item); Py_XDECREF(py_iterator); Py_XDECREF(py_exclude); return NULL; }
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; }
static PyObject * ExclusionFilter_obj_from_ccn(PyObject *py_exclusion_filter) { PyObject *py_obj_ExclusionFilter, *py_components = NULL; PyObject *py_o; struct ccn_charbuf *exclusion_filter; int r; struct ccn_buf_decoder decoder, *d; size_t start, stop; assert(g_type_ExclusionFilter); debug("ExclusionFilter_from_ccn start\n"); exclusion_filter = CCNObject_Get(EXCLUSION_FILTER, py_exclusion_filter); // 1) Create python object py_obj_ExclusionFilter = PyObject_CallObject(g_type_ExclusionFilter, NULL); JUMP_IF_NULL(py_obj_ExclusionFilter, error); // 2) Set ccn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. r = PyObject_SetAttrString(py_obj_ExclusionFilter, "ccn_data", py_exclusion_filter); JUMP_IF_NEG(r, error); // 3) Parse c structure and fill python attributes // using PyObject_SetAttrString // // self.components = None // # pyccn // self.ccn_data_dirty = False // self.ccn_data = None # backing charbuf py_components = PyList_New(0); JUMP_IF_NULL(py_components, error); r = PyObject_SetAttrString(py_obj_ExclusionFilter, "components", py_components); JUMP_IF_NEG(r, error); /* begin the actual parsing */ d = ccn_buf_decoder_start(&decoder, exclusion_filter->buf, exclusion_filter->length); r = ccn_buf_match_dtag(d, CCN_DTAG_Exclude); JUMP_IF_NEG(r, parse_error); ccn_buf_advance(d); r = ccn_buf_match_dtag(d, CCN_DTAG_Any); JUMP_IF_NEG(r, error); if (r) { ccn_buf_advance(d); ccn_buf_check_close(d); debug("got any: %d\n", r); py_o = Exclusion_Any_Obj(); JUMP_IF_NULL(py_o, error); r = PyList_Append(py_components, py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { start = d->decoder.token_index; r = ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Component, 0, -1); JUMP_IF_NEG(r, error); stop = d->decoder.token_index; debug("got name\n"); py_o = Exclusion_Name_Obj(exclusion_filter->buf, start, stop); r = PyList_Append(py_components, py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); r = ccn_buf_match_dtag(d, CCN_DTAG_Any); if (r) { ccn_buf_advance(d); ccn_buf_check_close(d); debug("got *any*: %d\n", r); py_o = Exclusion_Any_Obj(); JUMP_IF_NULL(py_o, error); r = PyList_Append(py_components, py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } } ccn_buf_check_close(d); JUMP_IF_NEG(d->decoder.state, parse_error); // 4) Return the created object debug("ExclusionFilter_from_ccn ends\n"); return py_obj_ExclusionFilter; parse_error: PyErr_SetString(g_PyExc_CCNExclusionFilterError, "error parsing the data"); error: Py_XDECREF(py_components); Py_XDECREF(py_obj_ExclusionFilter); return NULL; }
PyObject * _pyccn_cmd_SignedInfo_to_ccn(PyObject *UNUSED(self), PyObject *args, PyObject *kwds) { static char *kwlist[] = {"pubkey_digest", "type", "timestamp", "freshness", "final_block_id", "key_locator", NULL}; PyObject *py_pubkey_digest, *py_timestamp = Py_None, *py_final_block = Py_None, *py_key_locator = Py_None; struct ccn_charbuf *si; PyObject *py_si; int r; size_t publisher_key_id_size; const void *publisher_key_id; int type, freshness = -1; struct ccn_charbuf *timestamp = NULL, *finalblockid = NULL, *key_locator = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi|OiOO", kwlist, &py_pubkey_digest, &type, &py_timestamp, &freshness, &py_final_block, &py_key_locator)) return NULL; if (!PyBytes_Check(py_pubkey_digest)) { PyErr_SetString(PyExc_TypeError, "Must pass a Bytes as pubkey_digest"); return NULL; } else { publisher_key_id_size = PyBytes_GET_SIZE(py_pubkey_digest); publisher_key_id = PyBytes_AS_STRING(py_pubkey_digest); } if (py_timestamp != Py_None) { PyErr_SetString(PyExc_NotImplementedError, "Timestamp is not implemented yet"); return NULL; } else timestamp = NULL; if (py_final_block != Py_None) { char *s; Py_ssize_t len; if (!PyBytes_Check(py_final_block)) { PyErr_SetString(PyExc_TypeError, "Must pass a bytes as final block"); return NULL; } finalblockid = ccn_charbuf_create(); JUMP_IF_NULL_MEM(finalblockid, error); s = PyBytes_AS_STRING(py_final_block); len = PyBytes_GET_SIZE(py_final_block); r = ccn_charbuf_append_tt(finalblockid, len, CCN_BLOB); JUMP_IF_NEG_MEM(r, error); r = ccn_charbuf_append(finalblockid, s, len); JUMP_IF_NEG_MEM(r, error); } else finalblockid = NULL; if (py_key_locator == Py_None) key_locator = NULL; else if (CCNObject_IsValid(KEY_LOCATOR, py_key_locator)) key_locator = CCNObject_Get(KEY_LOCATOR, py_key_locator); else { PyErr_SetString(PyExc_TypeError, "key_locator needs to be a CCN KeyLocator object"); return NULL; } py_si = CCNObject_New_charbuf(SIGNED_INFO, &si); JUMP_IF_NULL(py_si, error); r = ccn_signed_info_create(si, publisher_key_id, publisher_key_id_size, timestamp, type, freshness, finalblockid, key_locator); ccn_charbuf_destroy(&finalblockid); if (r < 0) { Py_DECREF(py_si); PyErr_SetString(g_PyExc_CCNError, "Error while creating SignedInfo"); return NULL; } return py_si; error: ccn_charbuf_destroy(&finalblockid); return NULL; }
PyObject * SignedInfo_obj_from_ccn(PyObject *py_signed_info) { struct ccn_charbuf *signed_info; PyObject *py_obj_SignedInfo, *py_o; struct ccn_buf_decoder decoder, *d; size_t start, stop, size; const unsigned char *ptr; int r; signed_info = CCNObject_Get(SIGNED_INFO, py_signed_info); debug("SignedInfo_from_ccn start, size=%zd\n", signed_info->length); // 1) Create python object py_obj_SignedInfo = PyObject_CallObject(g_type_SignedInfo, NULL); if (!py_obj_SignedInfo) return NULL; // 2) Set ccn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. r = PyObject_SetAttrString(py_obj_SignedInfo, "ccn_data", py_signed_info); JUMP_IF_NEG(r, error); // 3) Parse c structure and fill python attributes // using PyObject_SetAttrString // based on chk_signing_params // from ccn_client.c // //outputs: // Note, it is ok that non-filled optional elements // are initialized to None (through the .py file __init__) // d = ccn_buf_decoder_start(&decoder, signed_info->buf, signed_info->length); if (!ccn_buf_match_dtag(d, CCN_DTAG_SignedInfo)) { PyErr_Format(g_PyExc_CCNSignedInfoError, "Error finding" " CCN_DTAG_SignedInfo (decoder state: %d)", d->decoder.state); goto error; } ccn_buf_advance(d); /* PublisherPublic Key */ //XXX: should we check for case when PublishePublicKeyDigest is not present? -dk start = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_PublisherPublicKeyDigest, 16, 64); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, d->buf, start, stop, &ptr, &size); if (r < 0) { PyErr_Format(g_PyExc_CCNSignedInfoError, "Error parsing" " CCN_DTAG_PublisherPublicKey (decoder state %d)", d->decoder.state); goto error; } // self.publisherPublicKeyDigest = None # SHA256 hash debug("PyObject_SetAttrString publisherPublicKeyDigest\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "publisherPublicKeyDigest", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); /* Timestamp */ start = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Timestamp, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, d->buf, start, stop, &ptr, &size); if (r < 0) { PyErr_Format(g_PyExc_CCNSignedInfoError, "Error parsing" " CCN_DTAG_Timestamp (decoder state %d)", d->decoder.state); goto error; } // self.timeStamp = None # CCNx timestamp debug("PyObject_SetAttrString timeStamp\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "timeStamp", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); /* Type */ assert(d->decoder.state >= 0); r = ccn_parse_optional_tagged_binary_number(d, CCN_DTAG_Type, 3, 3, CCN_CONTENT_DATA); if (d->decoder.state < 0) { PyErr_SetString(g_PyExc_CCNSignedInfoError, "Unable to parse type"); goto error; } py_o = _pyccn_Int_FromLong(r); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "type", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); /* start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Type, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_Type, d->buf, start, stop, &ptr, &size); if (r == 0) { // type = None # CCNx type // TODO: Provide a string representation with the Base64 mnemonic? debug("PyObject_SetAttrString type\n"); py_o = PyByteArray_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "type", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } */ /* FreshnessSeconds */ r = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds); if (r >= 0) { // self.freshnessSeconds = None debug("PyObject_SetAttrString freshnessSeconds\n"); py_o = _pyccn_Int_FromLong(r); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "freshnessSeconds", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* FinalBlockID */ #if 0 /* old code (left in case mine is wrong - dk) */ if (ccn_buf_match_dtag(d, CCN_DTAG_FinalBlockID)) { ccn_buf_advance(d); start = d->decoder.token_index; if (ccn_buf_match_some_blob(d)) ccn_buf_advance(d); stop = d->decoder.token_index; ccn_buf_check_close(d); if (d->decoder.state >= 0 && stop > start) { // self.finalBlockID = None fprintf(stderr, "PyObject_SetAttrString finalBlockID, len=%zd\n", stop - start); py_o = PyByteArray_FromStringAndSize((const char*) (d->buf + start), stop - start); PyObject_SetAttrString(py_obj_SignedInfo, "finalBlockID", py_o); Py_INCREF(py_o); } } #endif start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_FinalBlockID, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, d->buf, start, stop, &ptr, &size); if (r == 0) { // self.finalBlockID = None debug("PyObject_SetAttrString finalBlockID, len=%zd\n", size); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "finalBlockID", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* KeyLocator */ #if 0 /* Old code in case mine is wrong - dk */ start = d->decoder.token_index; if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) ccn_buf_advance_past_element(d); stop = d->decoder.token_index; if (d->decoder.state >= 0 && stop > start) { fprintf(stderr, "PyObject_SetAttrString keyLocator, len=%zd\n", stop - start); struct ccn_charbuf* keyLocator = ccn_charbuf_create(); ccn_charbuf_append(keyLocator, d->buf + start, stop - start); // self.keyLocator = None py_o = KeyLocator_obj_from_ccn(keyLocator); // it will free PyObject_SetAttrString(py_obj_SignedInfo, "keyLocator", py_o); Py_INCREF(py_o); } #endif /* * KeyLocator is not a BLOB, but an another structure, this requires * us to parse it differently */ start = d->decoder.token_index; if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) { struct ccn_charbuf *key_locator; PyObject *py_key_locator; r = ccn_buf_advance_past_element(d); if (r < 0) { PyErr_Format(g_PyExc_CCNSignedInfoError, "Error locating" " CCN_DTAG_KeyLocator (decoder state: %d, r: %d)", d->decoder.state, r); goto error; } stop = d->decoder.token_index; /* debug("element_index = %zd size = %zd nest = %d numval = %zd state = %d" " token_index %zd\n", d->decoder.element_index, d->decoder.index, d->decoder.nest, d->decoder.numval, d->decoder.state, d->decoder.token_index); assert(d->decoder.state >= 0); */ ptr = d->buf + start; size = stop - start; assert(size > 0); debug("PyObject_SetAttrString keyLocator, len=%zd\n", size); py_key_locator = CCNObject_New_charbuf(KEY_LOCATOR, &key_locator); JUMP_IF_NULL(py_key_locator, error); r = ccn_charbuf_append(key_locator, ptr, size); if (r < 0) { Py_DECREF(py_key_locator); PyErr_NoMemory(); goto error; } // self.keyLocator = None py_o = KeyLocator_obj_from_ccn(py_key_locator); Py_DECREF(py_key_locator); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "keyLocator", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } ccn_buf_check_close(d); if (d->decoder.state < 0) { PyErr_Format(g_PyExc_CCNSignedInfoError, "SignedInfo decoding error" " (decoder state: %d, numval: %zd)", d->decoder.state, d->decoder.numval); goto error; } // 4) Return the created object debug("SignedInfo_from_ccn ends\n"); return py_obj_SignedInfo; error: Py_DECREF(py_obj_SignedInfo); return NULL; }