int generate_key(int length, PyObject **py_private_key_ccn, PyObject **py_public_key_ccn, PyObject **py_public_key_digest, int *public_key_digest_len) { RSA *private_key_rsa; int r; seed_prng(); private_key_rsa = RSA_generate_key(length, 65537, NULL, NULL); save_seed(); if (!private_key_rsa) { unsigned int err; err = ERR_get_error(); PyErr_Format(g_PyExc_CCNKeyError, "Unable to generate digest from the" " key: %s", ERR_reason_error_string(err)); return -1; } r = ccn_keypair_from_rsa(0, private_key_rsa, py_private_key_ccn, py_public_key_ccn); if (r < 0) return -1; r = create_public_key_digest(private_key_rsa, py_public_key_digest, public_key_digest_len); if (r < 0) return -1; return 0; }
int put_key_der(int is_public_only, PyObject *py_key_der, PyObject **py_private_key_ndn, PyObject **py_public_key_ndn, PyObject **py_public_key_digest, int *public_key_digest_len) { struct ndn_pkey *key = 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 = (struct ndn_pkey*)d2i_PUBKEY(NULL, &key_der, der_len); else key = (struct ndn_pkey*)d2i_PrivateKey(EVP_PKEY_RSA, NULL, &key_der, der_len); 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, public_key_digest_len); JUMP_IF_NEG(r, error); return 0; error: return -1; }
int read_keypair_pem(FILE *fp, struct keypair** KP) { (*KP) = (struct keypair*) calloc(sizeof(struct keypair), 1); RSA *private_key_rsa; PEM_read_RSAPrivateKey(fp, &private_key_rsa, NULL, NULL); ccn_keypair_from_rsa(private_key_rsa, &(*KP)->private_key, &(*KP)->public_key); create_public_key_digest(private_key_rsa, &(*KP)->public_key_digest, &(*KP)->public_key_digest_len); RSA_free(private_key_rsa); return 0; }
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 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 struct ndn_keystore* Key_to_ndn_keystore(PyObject* py_key) { // An imperfect conversion here, but... // This is supposed to be an opaque type. // We borrow this from ndn_keystore.c // so that we can work with the ndn hashtable // and do Key_to_keystore... but this whole method may not be // ever needed, as the ndn_keystore type seems // to be primarily for the use of the library internally? struct ndn_keystore_private { int initialized; EVP_PKEY *private_key; EVP_PKEY *public_key; X509 *certificate; ssize_t pubkey_digest_length; unsigned char pubkey_digest[SHA256_DIGEST_LENGTH]; }; struct ndn_keystore_private* keystore = calloc(1, sizeof(struct ndn_keystore_private)); keystore->initialized = 1; // TODO: need to INCREF here? keystore->private_key = (EVP_PKEY*) PyCObject_AsVoidPtr(PyObject_GetAttrString(py_key, "ndn_data_private")); keystore->public_key = (EVP_PKEY*) PyCObject_AsVoidPtr(PyObject_GetAttrString(py_key, "ndn_data_public")); RSA* private_key_rsa = EVP_PKEY_get1_RSA((EVP_PKEY*) keystore->private_key); unsigned char* public_key_digest; size_t public_key_digest_len; create_public_key_digest(private_key_rsa, &public_key_digest, &public_key_digest_len); memcpy(keystore->pubkey_digest, public_key_digest, public_key_digest_len); keystore->pubkey_digest_length = public_key_digest_len; free(public_key_digest); free(private_key_rsa); return(struct ndn_keystore*) keystore; }
int generate_key(int length, PyObject **py_private_key_ndn, PyObject **py_public_key_ndn, PyObject **py_public_key_digest, int *public_key_digest_len) { RSA *private_key_rsa; struct ndn_pkey *private_key = NULL; int r; seed_prng(); private_key_rsa = RSA_generate_key(length, 65537, NULL, NULL); private_key = (struct ndn_pkey *)EVP_PKEY_new(); EVP_PKEY_assign_RSA ((EVP_PKEY *)private_key, private_key_rsa); save_seed (); if (!private_key_rsa || !private_key) { unsigned int err; err = ERR_get_error(); PyErr_Format(g_PyExc_NDNKeyError, "Unable to generate the" " key: %s", ERR_reason_error_string(err)); return -1; } r = ndn_keypair(0, private_key, py_private_key_ndn, py_public_key_ndn); if (r < 0) return -1; r = create_public_key_digest(private_key, py_public_key_digest, public_key_digest_len); if (r < 0) return -1; EVP_PKEY_free ((EVP_PKEY*)private_key); return 0; }
int read_key_pem(FILE *fp, PyObject **py_private_key_ndn, PyObject **py_public_key_ndn, PyObject **py_public_key_digest, int *public_key_digest_len, char *password) { struct ndn_pkey *private_key = NULL; PyObject *py_private_key = NULL, *py_public_key = NULL; unsigned long err, reason; fpos_t fpos; int r; int public_only; r = fgetpos(fp, &fpos); JUMP_IF_NEG(r, errno_error); private_key = (struct ndn_pkey *)PEM_read_PrivateKey(fp, NULL, NULL, password); if (private_key) { public_only = 0; goto success; } err = ERR_get_error(); reason = ERR_GET_REASON(err); /* 108 was meaning that start line isn't recognized */ if (reason == 108) { r = fsetpos(fp, &fpos); JUMP_IF_NEG(r, errno_error); private_key = (struct ndn_pkey *)PEM_read_PUBKEY (fp, NULL, NULL, NULL); if (private_key) { public_only = 1; goto success; } err = ERR_get_error(); reason = ERR_GET_REASON(err); } { char buf[256]; ERR_error_string_n(err, buf, sizeof(buf)); PyErr_Format(g_PyExc_NDNKeyError, "Unable to read Private Key: %s", buf); goto error; } success: r = ndn_keypair(public_only, private_key, py_private_key_ndn, py_public_key_ndn); JUMP_IF_NEG(r, error); r = create_public_key_digest(private_key, py_public_key_digest, public_key_digest_len); JUMP_IF_NEG(r, error); return 0; errno_error: PyErr_SetFromErrno(PyExc_IOError); error: Py_XDECREF(py_private_key); Py_XDECREF(py_public_key); if (private_key) EVP_PKEY_free((EVP_PKEY *)private_key); return -1; }
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; }
int read_key_pem(FILE *fp, PyObject **py_private_key_ccn, PyObject **py_public_key_ccn, PyObject **py_public_key_digest, int *public_key_digest_len) { RSA *private_key_rsa = NULL; PyObject *py_private_key = NULL, *py_public_key = NULL; unsigned long err, reason; fpos_t fpos; int r; int public_only; r = fgetpos(fp, &fpos); JUMP_IF_NEG(r, errno_error); private_key_rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); if (private_key_rsa) { public_only = 0; goto success; } err = ERR_get_error(); reason = ERR_GET_REASON(err); /* 108 was meaning that start line isn't recognized */ if (reason == 108) { r = fsetpos(fp, &fpos); JUMP_IF_NEG(r, errno_error); private_key_rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL); if (private_key_rsa) { public_only = 1; goto success; } err = ERR_get_error(); reason = ERR_GET_REASON(err); } { char buf[256]; ERR_error_string_n(err, buf, sizeof(buf)); PyErr_Format(g_PyExc_CCNKeyError, "Unable to read Private Key: %s", buf); goto error; } success: r = ccn_keypair_from_rsa(public_only, private_key_rsa, py_private_key_ccn, py_public_key_ccn); JUMP_IF_NEG(r, error); r = create_public_key_digest(private_key_rsa, py_public_key_digest, public_key_digest_len); JUMP_IF_NEG(r, error); RSA_free(private_key_rsa); return 0; errno_error: PyErr_SetFromErrno(PyExc_IOError); error: Py_XDECREF(py_private_key); Py_XDECREF(py_public_key); if (private_key_rsa) RSA_free(private_key_rsa); return -1; }