static PyObject * Exclusion_Name_Obj(unsigned char *buf, size_t start, size_t stop) { struct ccn_charbuf *name; PyObject *py_name, *res; int r; py_name = CCNObject_New_charbuf(NAME, &name); JUMP_IF_NULL(py_name, error); r = ccn_name_init(name); JUMP_IF_NEG_MEM(r, error); r = ccn_name_append_components(name, buf, start, stop); JUMP_IF_NEG_MEM(r, error); res = Name_obj_from_ccn(py_name); Py_DECREF(py_name); return res; error: Py_XDECREF(py_name); return NULL; }
PyObject * get_key_pem_public(const struct ndn_pkey *key_ndn) { unsigned long err; BIO *bio; BUF_MEM *bufmem; int r; PyObject *py_res; bio = BIO_new(BIO_s_mem()); JUMP_IF_NULL(bio, openssl_error); r = PEM_write_bio_PUBKEY(bio, (EVP_PKEY *) key_ndn); if (!r) goto openssl_error; BIO_get_mem_ptr(bio, &bufmem); py_res = PyBytes_FromStringAndSize(bufmem->data, bufmem->length); r = BIO_free(bio); if (!r) goto openssl_error; return py_res; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_NDNKeyError, "Unable to obtain PEM: %s", ERR_reason_error_string(err)); BIO_free(bio); return NULL; }
int put_key_pem(int is_public_only, PyObject *py_key_pem, PyObject **py_private_key_ccn, PyObject **py_public_key_ccn, PyObject **py_public_key_digest) { unsigned char *key_pem; Py_ssize_t pem_len; RSA *key_rsa = NULL; BIO *bio = NULL; int r; unsigned long err; r = PyBytes_AsStringAndSize(py_key_pem, (char **) &key_pem, &pem_len); JUMP_IF_NEG(r, error); bio = BIO_new_mem_buf(key_pem, pem_len); JUMP_IF_NULL(bio, openssl_error); if (is_public_only) key_rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL); else key_rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); JUMP_IF_NULL(key_rsa, openssl_error); r = ccn_keypair_from_rsa(is_public_only, key_rsa, py_private_key_ccn, py_public_key_ccn); JUMP_IF_NEG(r, error); r = create_public_key_digest(key_rsa, py_public_key_digest, NULL); JUMP_IF_NEG(r, error); RSA_free(key_rsa); return 0; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_CCNKeyError, "Unable to parse key: %s", ERR_reason_error_string(err)); error: RSA_free(key_rsa); BIO_free(bio); return -1; }
int put_key_pem(int is_public_only, PyObject *py_key_pem, PyObject **py_private_key_ndn, PyObject **py_public_key_ndn, PyObject **py_public_key_digest, char *password) { unsigned char *key_pem; Py_ssize_t pem_len; struct ndn_pkey *key = NULL; BIO *bio = NULL; int r; unsigned long err; r = PyBytes_AsStringAndSize(py_key_pem, (char **) &key_pem, &pem_len); JUMP_IF_NEG(r, error); bio = BIO_new_mem_buf(key_pem, pem_len); JUMP_IF_NULL(bio, openssl_error); if (is_public_only) key = (struct ndn_pkey*)PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); else key = (struct ndn_pkey*)PEM_read_bio_PrivateKey(bio, NULL, NULL, password); JUMP_IF_NULL(key, openssl_error); r = ndn_keypair(is_public_only, key, py_private_key_ndn, py_public_key_ndn); JUMP_IF_NEG(r, error); r = create_public_key_digest(key, py_public_key_digest, NULL); JUMP_IF_NEG(r, error); return 0; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_NDNKeyError, "Unable to parse key: %s", ERR_reason_error_string(err)); error: EVP_PKEY_free ((EVP_PKEY *)key); BIO_free(bio); return -1; }
static int create_key_digest(const unsigned char *dkey, size_t dkey_size, unsigned char **o_key_digest, size_t *o_key_digest_size) { struct ndn_digest *digest; unsigned char *key_digest = NULL; size_t key_digest_size; int r; assert(o_key_digest); assert(o_key_digest_size); digest = ndn_digest_create(NDN_DIGEST_SHA256); JUMP_IF_NULL(digest, error); ndn_digest_init(digest); key_digest_size = ndn_digest_size(digest); key_digest = malloc(key_digest_size); JUMP_IF_NULL(key_digest, error); r = ndn_digest_update(digest, dkey, dkey_size); JUMP_IF_NEG(r, error); r = ndn_digest_final(digest, key_digest, key_digest_size); JUMP_IF_NEG(r, error); ndn_digest_destroy(&digest); *o_key_digest = key_digest; *o_key_digest_size = key_digest_size; return 0; error: PyErr_SetString(g_PyExc_NDNKeyError, "unable to generate key digest"); if (key_digest) free(key_digest); ndn_digest_destroy(&digest); return -1; }
PyObject * get_key_pem_private(const struct ccn_pkey *private_key_ccn) { unsigned long err; RSA *private_key_rsa = NULL; BIO *bio; BUF_MEM *bufmem; int r; PyObject *py_res; bio = BIO_new(BIO_s_mem()); JUMP_IF_NULL(bio, openssl_error); private_key_rsa = EVP_PKEY_get1_RSA((EVP_PKEY *) private_key_ccn); JUMP_IF_NULL(private_key_rsa, openssl_error); r = PEM_write_bio_RSAPrivateKey(bio, private_key_rsa, NULL, NULL, 0, NULL, NULL); RSA_free(private_key_rsa); private_key_rsa = NULL; if (!r) goto openssl_error; BIO_get_mem_ptr(bio, &bufmem); py_res = PyBytes_FromStringAndSize(bufmem->data, bufmem->length); r = BIO_free(bio); if (!r) goto openssl_error; return py_res; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_CCNKeyError, "Unable to obtain PEM: %s", ERR_reason_error_string(err)); RSA_free(private_key_rsa); BIO_free(bio); return NULL; }
int ccn_keypair_from_rsa(int public_only, RSA *private_key_rsa, PyObject **py_private_key_ccn, PyObject **py_public_key_ccn) { struct ccn_pkey *private_key = NULL, *public_key = NULL; PyObject *py_private_key = NULL, *py_public_key = NULL; unsigned int err; int r; RSA *public_key_rsa; if (!public_only && py_private_key_ccn) { private_key = (struct ccn_pkey *) EVP_PKEY_new(); JUMP_IF_NULL(private_key, openssl_error); py_private_key = CCNObject_New(PKEY_PRIV, private_key); JUMP_IF_NULL(py_private_key, error); r = EVP_PKEY_set1_RSA((EVP_PKEY*) private_key, private_key_rsa); JUMP_IF_NEG(r, openssl_error); } if (py_public_key_ccn) { public_key = (struct ccn_pkey *) EVP_PKEY_new(); JUMP_IF_NULL(public_key, openssl_error); py_public_key = CCNObject_New(PKEY_PUB, public_key); JUMP_IF_NULL(py_public_key, error); public_key_rsa = RSAPublicKey_dup(private_key_rsa); JUMP_IF_NULL(public_key_rsa, openssl_error); r = EVP_PKEY_set1_RSA((EVP_PKEY *) public_key, public_key_rsa); RSA_free(public_key_rsa); JUMP_IF_NULL(r, error); } if (py_private_key_ccn) { *py_private_key_ccn = public_only ? (Py_INCREF(Py_None), Py_None) : py_private_key; } if (py_public_key_ccn) *py_public_key_ccn = py_public_key; return 0; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_CCNKeyError, "Unable to generate keypair from the key:" " %s", ERR_reason_error_string(err)); error: if (!py_public_key && public_key) ccn_pubkey_free(public_key); Py_XDECREF(py_public_key); if (!py_private_key && private_key) ccn_pubkey_free(private_key); Py_XDECREF(py_private_key); return -1; }
int put_key_der(int is_public_only, PyObject *py_key_der, PyObject **py_private_key_ccn, PyObject **py_public_key_ccn, PyObject **py_public_key_digest, int *public_key_digest_len) { RSA *key_rsa = NULL; const unsigned char *key_der; Py_ssize_t der_len; int r; unsigned long err; r = PyBytes_AsStringAndSize(py_key_der, (char **) &key_der, &der_len); JUMP_IF_NEG(r, error); if (is_public_only) key_rsa = d2i_RSA_PUBKEY(NULL, &key_der, der_len); else key_rsa = d2i_RSAPrivateKey(NULL, &key_der, der_len); //above changes the key_der, so we set it to NULL for safety to not use it key_der = NULL; JUMP_IF_NULL(key_rsa, openssl_error); r = ccn_keypair_from_rsa(is_public_only, key_rsa, py_private_key_ccn, py_public_key_ccn); JUMP_IF_NEG(r, error); r = create_public_key_digest(key_rsa, py_public_key_digest, public_key_digest_len); JUMP_IF_NEG(r, error); RSA_free(key_rsa); return 0; openssl_error: err = ERR_get_error(); { char buf[256]; ERR_error_string_n(err, buf, sizeof(buf)); PyErr_Format(g_PyExc_CCNKeyError, "Unable to read Private Key: %s", buf); } error: RSA_free(key_rsa); return -1; }
int create_public_key_digest(struct ndn_pkey *key, PyObject **py_public_key_digest, int *public_key_digest_len) { unsigned int err; unsigned char *public_key_der = NULL; size_t der_len; unsigned char *key_digest; size_t key_digest_size; PyObject *py_digest = NULL; int r; assert(key); assert(py_public_key_digest); r = i2d_PUBKEY((EVP_PKEY *)key, &public_key_der); if (r < 0) { goto openssl_error; } der_len = r; r = create_key_digest(public_key_der, der_len, &key_digest, &key_digest_size); free(public_key_der); public_key_der = NULL; JUMP_IF_NEG(r, error); py_digest = PyBytes_FromStringAndSize((char *) key_digest, key_digest_size); JUMP_IF_NULL(py_digest, error); *py_public_key_digest = py_digest; if (public_key_digest_len) *public_key_digest_len = key_digest_size; return 0; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_NDNKeyError, "Unable to generate digest from the key:" " %s", ERR_reason_error_string(err)); error: if (public_key_der) free(public_key_der); return -1; }
PyObject * get_key_der_public(struct ndn_pkey *public_key_ndn) { PyObject *result; unsigned long err; unsigned char *public_key_der = NULL; int der_len; der_len = i2d_PUBKEY((EVP_PKEY *) public_key_ndn, &public_key_der); JUMP_IF_NEG(der_len, openssl_error); result = PyBytes_FromStringAndSize((char *) public_key_der, der_len); JUMP_IF_NULL(result, error); return result; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_NDNKeyError, "Unable to write Public Key: %s", ERR_reason_error_string(err)); error: return NULL; }
PyObject * get_key_pem_private(const struct ndn_pkey *private_key_ndn, char *password) { unsigned long err; BIO *bio; BUF_MEM *bufmem; int r; PyObject *py_res; bio = BIO_new(BIO_s_mem()); JUMP_IF_NULL(bio, openssl_error); if (password) { r = PEM_write_bio_PKCS8PrivateKey (bio, (EVP_PKEY *) private_key_ndn, EVP_aes_256_cbc (), NULL, 0, NULL, password); } else { r = PEM_write_bio_PrivateKey(bio, (EVP_PKEY *) private_key_ndn, NULL, NULL, 0, NULL, NULL); } if (!r) goto openssl_error; BIO_get_mem_ptr(bio, &bufmem); py_res = PyBytes_FromStringAndSize(bufmem->data, bufmem->length); r = BIO_free(bio); if (!r) goto openssl_error; return py_res; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_NDNKeyError, "Unable to obtain PEM: %s", ERR_reason_error_string(err)); BIO_free(bio); 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 * 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; }
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 * Key_obj_from_ndn(PyObject *py_key_ndn) { struct ndn_pkey *key_ndn; PyObject *py_obj_Key; RSA *private_key_rsa = NULL; PyObject *py_private_key_ndn = NULL, *py_public_key_ndn = NULL, *py_public_key_digest = NULL; int public_key_digest_len; int r, public_only; PyObject* py_o; assert(g_type_Key); debug("Key_from_ndn start\n"); if (NDNObject_IsValid(PKEY_PRIV, py_key_ndn)) { public_only = 0; key_ndn = NDNObject_Get(PKEY_PRIV, py_key_ndn); } else if (NDNObject_IsValid(PKEY_PUB, py_key_ndn)) { public_only = 1; key_ndn = NDNObject_Get(PKEY_PUB, py_key_ndn); } else { PyErr_SetString(PyExc_TypeError, "expected NDN key"); return NULL; } // 1) Create python object py_obj_Key = PyObject_CallObject(g_type_Key, NULL); JUMP_IF_NULL(py_obj_Key, error); // 2) Parse c structure and fill python attributes // If this is a private key, split private and public keys // There is probably a less convoluted way to do this than pulling // it out to RSA // Also, create the digest... // These non-ndn functions assume the NDN defaults, RSA + SHA256 private_key_rsa = ndn_key_to_rsa(key_ndn); JUMP_IF_NULL(private_key_rsa, error); r = ndn_keypair_from_rsa(public_only, private_key_rsa, &py_private_key_ndn, &py_public_key_ndn); JUMP_IF_NEG(r, error); r = create_public_key_digest(private_key_rsa, &py_public_key_digest, &public_key_digest_len); RSA_free(private_key_rsa); private_key_rsa = NULL; JUMP_IF_NEG(r, error); // ndn_digest has a more convoluted API, with examples // in ndn_client, but *for now* it boils down to the same thing. /* type */ py_o = PyUnicode_FromString("RSA"); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_Key, "type", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); /* publicKeyID */ r = PyObject_SetAttrString(py_obj_Key, "publicKeyID", py_public_key_digest); Py_CLEAR(py_public_key_digest); JUMP_IF_NEG(r, error); // 3) Set ndn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. // privateKey r = PyObject_SetAttrString(py_obj_Key, "ndn_data_private", py_private_key_ndn); Py_CLEAR(py_private_key_ndn); JUMP_IF_NEG(r, error); // publicKey r = PyObject_SetAttrString(py_obj_Key, "ndn_data_public", py_public_key_ndn); Py_CLEAR(py_public_key_ndn); JUMP_IF_NEG(r, error); // 4) Return the created object debug("Key_from_ndn ends\n"); return py_obj_Key; error: Py_XDECREF(py_private_key_ndn); Py_XDECREF(py_public_key_ndn); Py_XDECREF(py_public_key_digest); RSA_free(private_key_rsa); Py_XDECREF(py_obj_Key); 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; }
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; }
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_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; }
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; }
int create_public_key_digest(RSA *private_key_rsa, PyObject **py_public_key_digest, int *public_key_digest_len) { unsigned int err; unsigned char *public_key_der = NULL; size_t der_len; unsigned char *key_digest; size_t key_digest_size; PyObject *py_digest = NULL; int r; EVP_PKEY *public_key = NULL; RSA *public_key_rsa = NULL; assert(private_key_rsa); assert(py_public_key_digest); public_key = EVP_PKEY_new(); JUMP_IF_NULL(public_key, openssl_error); public_key_rsa = RSAPublicKey_dup(private_key_rsa); JUMP_IF_NULL(public_key_rsa, openssl_error); r = EVP_PKEY_set1_RSA(public_key, public_key_rsa); RSA_free(public_key_rsa); public_key_rsa = NULL; JUMP_IF_NEG(r, openssl_error); r = i2d_PUBKEY(public_key, &public_key_der); EVP_PKEY_free(public_key); public_key = NULL; if (r < 0) { free(public_key_der); goto openssl_error; } der_len = r; r = create_key_digest(public_key_der, der_len, &key_digest, &key_digest_size); free(public_key_der); public_key_der = NULL; JUMP_IF_NEG(r, error); py_digest = PyBytes_FromStringAndSize((char *) key_digest, key_digest_size); JUMP_IF_NULL(py_digest, error); *py_public_key_digest = py_digest; if (public_key_digest_len) *public_key_digest_len = key_digest_size; return 0; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_CCNKeyError, "Unable to generate digest from the key:" " %s", ERR_reason_error_string(err)); error: if (public_key_rsa) RSA_free(public_key_rsa); if (public_key) EVP_PKEY_free(public_key); if (public_key_der) free(public_key_der); return -1; }