Hanson Duan
Hanson Duan

Reputation: 19

Incorrect message length when using C python api

I'm trying to extend libhydrogen (open source found here: https://github.com/jedisct1/libhydrogen/) to support calls to the underlying library in Python. However, I ran into a strange issue. Specifically I have the following code:

static PyObject* crypto_secretbox_encrypt(PyObject* self, PyObject* args){
    char* m;
    size_t mlen;
    uint64_t msg_id;
    char *ctx;
    size_t ctx_len;
    const uint8_t *key; //this shouldn't matter its secret
    size_t key_len;
    PyArg_ParseTuple(args, "s#|K|s#|s#", &m, &mlen, &msg_id, &ctx, &ctx_len, &key, &key_len); //only s# accepts null bytes, need to random pointers to store lengths
    //printf("Parsed \n");
    //printf("MSG: %s, MSG_ID: %" PRIu64 ", CTX: %s\n", m, msg_id, ctx);
    if(ctx_len != hydro_secretbox_CONTEXTBYTES){
        PyErr_Format(PyExc_ValueError, "Context not of correct size: Received %lu bytes", ctx_len);
        return NULL;
    }

    if(key_len != hydro_secretbox_KEYBYTES){
        PyErr_Format(PyExc_ValueError, "Key not of correct size: Received %lu bytes", key_len);
        return NULL;
    }

Which is able to successfully parse the length of ctx, however, when it gets to the key it gets thrown the error,

  File "cryptotest.py", line 7, in <module>
    c1 = crypto.secretbox_encrypt("message1", 0, "\x00"*8, '\x00'*32);
ValueError: Key not of correct size: Received 140123308032032 bytes

Any ideas on why I'm unable to successfully parse the key length?

Upvotes: 0

Views: 334

Answers (1)

user2357112
user2357112

Reputation: 280993

You've specified the length as a size_t. The s# format does not take a size_t. It takes an int or Py_ssize_t, depending on whether the PY_SSIZE_T_CLEAN macro was #defined before including Python.h.

Note: For all # variants of formats (s#, y#, etc.), the type of the length argument (int or Py_ssize_t) is controlled by defining the macro PY_SSIZE_T_CLEAN before including Python.h. If the macro was defined, length is a Py_ssize_t rather than an int. This behavior will change in a future Python version to only support Py_ssize_t and drop int support. It is best to always define PY_SSIZE_T_CLEAN.

Upvotes: 2

Related Questions