TooTallNate / ref-struct

Create ABI-compliant "struct" instances on top of Buffers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Array of Struct

microshine opened this issue · comments

Hello!

I'm wrapping PKCS11 lib and I have a problem with Array of Struct. I have next C function and types

typedef CK_ULONG          CK_SESSION_HANDLE;
typedef CK_ULONG          CK_OBJECT_HANDLE;

/* CK_ATTRIBUTE is a structure that includes the type, length
 * and value of an attribute */
typedef struct CK_ATTRIBUTE {
  CK_ATTRIBUTE_TYPE type;
  CK_VOID_PTR       pValue;

  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
  CK_ULONG          ulValueLen;  /* in bytes */
} CK_ATTRIBUTE;
typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;

/* C_GetAttributeValue obtains the value of one or more object
 * attributes. */
CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
#ifdef CK_NEED_ARG_LIST
(
  CK_SESSION_HANDLE hSession,   /* the session's handle */
  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
  CK_ULONG          ulCount     /* attributes in template */
);
#endif

My JavaScript code is:

cki.CK_ULONG = "uint32";
cki.CK_SESSION_HANDLE = cki.CK_ULONG;

cki.CK_ATTRIBUTE_TYPE = cki.CK_ULONG;

/* CK_ATTRIBUTE is a structure that includes the type, length
 * and value of an attribute */
cki.CK_ATTRIBUTE = struct({
  type: cki.CK_ATTRIBUTE_TYPE,
  pValue: cki.CK_VOID_PTR,

  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
  ulValueLen: cki.CK_ULONG  /* in bytes */
});

cki.CK_ATTRIBUTE_PTR = ref.refType(cki.CK_ATTRIBUTE);

var C_GetAttributeValue = ffi(lib_path, "C_GetAttributeValue":[cki.CK_RV, [cki.CK_SESSION_HANDLE, cki.CK_OBJECT_HANDLE, cki.CK_ATTRIBUTE_PTR, cki.CK_ULONG]]);

Run code is:

//call function
function Test(hSession, hObject){
    var $label = new (ArrayType(cki.CK_UTF8CHAR))(80);
    var TemplateArray = ArrayType(cki.CK_ATTRIBUTE);
    var template1 = new cki.CK_ATTRIBUTE({
        "type": cki.CKA_LABEL, 
        pValue: $label.ref(), 
        ulValueLen: 80}
    );

    var template = new TemplateArray(1);
    template[0] = template1; 

    var res = this.cki.C_GetAttributeValue(hSession, hObject, template.ref(), 1);
    if (res == cki.CKR_OK) {
        console.log("Ok");
    }
    else{
        console.log("Wrong %d",res);
    }
}

If I call Test function I have result Error - Wrong params (code 7 or 18).
What is wrong?

Here is a sample of C function:

void
show_key_info(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key)
{
     CK_RV rv;
     CK_UTF8CHAR *label = (CK_UTF8CHAR *) malloc(80);
     CK_BYTE *id = (CK_BYTE *) malloc(10);
     size_t label_len;
     char *label_str;

     memset(id, 0, 10);

     CK_ATTRIBUTE template[] = {
          {CKA_LABEL, label, 80},
          {CKA_ID, id, 1}
     };

     rv = C_GetAttributeValue(session, key, template, 2);
     check_return_value(rv, "get attribute value");

     fprintf(stdout, "Found a key:\n");
     label_len = template[0].ulValueLen;
     if (label_len > 0) {
          label_str = malloc(label_len + 1);
          memcpy(label_str, label, label_len);
          label_str[label_len] = '\0';
          fprintf(stdout, "\tKey label: %s\n", label_str);
          free(label_str);
     } else {
          fprintf(stdout, "\tKey label too large, or not found\n");
     }
     if (template[1].ulValueLen > 0) {
          fprintf(stdout, "\tKey ID: %02x\n", id[0]);
     } else {
          fprintf(stdout, "\tKey id too large, or not found\n");
     }

     free(label);
     free(id);
}

I have resolved my problem. But I don't use ref-array.

function _getAttribute(cki, hSession, hObject, atrType, len) {
    Debug("Attribute type: %d", atrType);
    var $value = null;

    if (!len)
        len = 0;
    else
        $value = new Buffer(len);

    var tpl = new CKI.CK_ATTRIBUTE({
        "type": atrType,
        pValue: $value,
        ulValueLen: len
    });

    Debug('C_GetAttributeValue');
    var res = cki.C_GetAttributeValue(hSession, hObject, tpl.ref(), 1);
    Utils.check_cki_res(res, "C_GetAttributeValue");
    Debug('Attribute.langth: %d', tpl.ulValueLen);

    var r = tpl.ulValueLen;
    if ($value) {
        r = $value.slice(0, tpl.ulValueLen)
    }
    return r;
}