Example #1
0
void kssl_repeat_op_ping(connection *c, int repeat)
{
    char hello[255];
    kssl_header echo1;
    kssl_operation req, resp;
    kssl_header *h;
    int i;
    BYTE *payload = malloc(255 + 1);
    test("Repeat KSSL_OP_PING %d times (%p)", repeat, c);
    echo1.version_maj = KSSL_VERSION_MAJ;
    echo1.id = 0x12345679;
    zero_operation(&req);
    req.is_opcode_set = 1;
    req.is_payload_set = 1;
    req.opcode = KSSL_OP_PING;
    req.payload_len = 255 + 1;
    req.payload = payload;
    for (i = 0; i < repeat; i++) {
        sprintf(hello, "Hello, World! %d", i);
        memcpy((char *)payload, hello, strlen(hello)+1);
        req.payload_len = strlen(hello)+1;
        h = kssl(c->ssl, &echo1, &req);
        test_assert(h->id == echo1.id);
        test_assert(h->version_maj == KSSL_VERSION_MAJ);
        parse_message_payload(h->data, h->length, &resp);
        test_assert(resp.opcode == KSSL_OP_PONG);
        test_assert(resp.payload_len == req.payload_len);
        test_assert(strncmp((char *)resp.payload, (char *)req.payload, strlen(hello)) == 0);
        free(h->data);
        free(h);
    }
    ok(0);
    free(payload);
}
Example #2
0
void kssl_op_ping_payload(connection *c)
{
    const char *hello = "Hello, World!";
    kssl_operation req, resp;
    kssl_header echo1;
    kssl_header *h;
    BYTE *payload;
    test("KSSL_OP_PING with payload (%p)", c);

    payload = malloc(strlen(hello) + 1);
    echo1.version_maj = KSSL_VERSION_MAJ;
    echo1.id = 0x12345679;
    zero_operation(&req);
    req.is_opcode_set = 1;
    req.is_payload_set = 1;
    req.opcode = KSSL_OP_PING;
    req.payload_len = strlen(hello);
    req.payload = payload;
    memcpy((char *)payload, hello, strlen(hello));
    h = kssl(c->ssl, &echo1, &req);
    test_assert(h->id == echo1.id);
    test_assert(h->version_maj == KSSL_VERSION_MAJ);
    parse_message_payload(h->data, h->length, &resp);
    test_assert(resp.opcode == KSSL_OP_PONG);
    test_assert(resp.payload_len == req.payload_len);
    test_assert(strncmp((char *)resp.payload, (char *)req.payload, strlen(hello)) == 0);
    ok(h);
    free(payload);
}
Example #3
0
void kssl_bad_opcode(connection *c)
{
    kssl_header bad;
    kssl_operation req, resp;
    kssl_header *h;

    test("Bad KSSL opcode (%p)", c);
    bad.version_maj = KSSL_VERSION_MAJ;
    bad.version_min = KSSL_VERSION_MIN;
    bad.id = 0x12345678;
    bad.length = 0; // to be overridden by serialization
    zero_operation(&req);
    req.is_opcode_set = 1;
    req.is_payload_set = 1;
    req.opcode = 0xBB;
    req.payload_len = 0;
    h = kssl(c->ssl, &bad, &req);
    test_assert(h->id == bad.id);
    test_assert(h->version_maj == KSSL_VERSION_MAJ);
    parse_message_payload(h->data, h->length, &resp);
    test_assert(resp.opcode == KSSL_OP_ERROR);
    test_assert(resp.payload_len == 1);
    test_assert(resp.payload[0] == KSSL_ERROR_BAD_OPCODE);
    ok(h);
}
Example #4
0
// dump_payload: print out the payload from a KSSL operation in hex
void dump_payload(int l, BYTE *p)
{
    kssl_operation request;

    if (!debug) return;

    if (l > 0) {
        int i;
        printf("  Payload Raw: ");
        for (i = 0; i < l; ++i) {
            if ((i != 0) && (i%16 == 0)) {
                printf("\n           ");
            }
            printf("%02x ", p[i]);
        }
        printf("\n");
    }
    parse_message_payload(p, l, &request);

    dump_request(&request);
}
Example #5
0
void kssl_op_ping_bad_version(connection *c)
{
    kssl_header echo0;
    kssl_operation req, resp;
    kssl_header *h;
    test("KSSL_OP_PING with bad version (%p)", c);
    echo0.id = 0x12345678;
    echo0.version_maj = KSSL_VERSION_MAJ+1;
    zero_operation(&req);
    req.is_opcode_set = 1;
    req.is_payload_set = 1;
    req.opcode = KSSL_OP_PING;
    req.payload_len = 0;
    h = kssl(c->ssl, &echo0, &req);
    test_assert(h->version_maj == KSSL_VERSION_MAJ);
    test_assert(h->id == echo0.id);
    parse_message_payload(h->data, h->length, &resp);
    test_assert(resp.opcode == KSSL_OP_ERROR);
    test_assert(resp.payload_len == 1);
    test_assert(resp.payload[0] == KSSL_ERROR_VERSION_MISMATCH);
    ok(h);
}
Example #6
0
void kssl_op_error(connection *c)
{
    kssl_header echo0;
    kssl_operation req, resp;
    kssl_header *h;
    test("KSSL_OP_ERROR (%p)", c);

    echo0.version_maj = KSSL_VERSION_MAJ;
    echo0.id = 0x12345678;
    zero_operation(&req);
    req.is_opcode_set = 1;
    req.is_payload_set = 1;
    req.opcode = KSSL_OP_ERROR;
    req.payload_len = 0;
    h = kssl(c->ssl, &echo0, &req);
    test_assert(h->id == echo0.id);
    test_assert(h->version_maj == KSSL_VERSION_MAJ);
    parse_message_payload(h->data, h->length, &resp);
    test_assert(resp.opcode == KSSL_OP_ERROR);
    test_assert(resp.payload_len == 1);
    test_assert(resp.payload[0] == KSSL_ERROR_UNEXPECTED_OPCODE);
    ok(h);
}
Example #7
0
// kssl_operate: create a serialized response from a KSSL request
// header and payload
kssl_error_code kssl_operate(kssl_header *header,
                             BYTE *payload,
                             pk_list privates,
                             BYTE **out_response,
                             int *out_response_len) {
  kssl_error_code err = KSSL_ERROR_NONE;
  BYTE *local_resp = NULL;
  int local_resp_len = 0;

  // Parse the indices of the items out of the payload
  kssl_header out_header;
  kssl_operation request;
  kssl_operation response;
  BYTE *out_payload = NULL;
  zero_operation(&request);
  zero_operation(&response);

  *out_response = 0;
  *out_response_len = 0;

  // Extract the items from the payload
  err = parse_message_payload(payload, header->length, &request);
  if (err != KSSL_ERROR_NONE) {
    goto exit;
  }

  if (silent == 0) {
    log_operation(header, &request);
  }

  switch (request.opcode) {
    // Other side sent response, error or pong: unexpected
    case KSSL_OP_RESPONSE:
    case KSSL_OP_ERROR:
    case KSSL_OP_PONG:
    {
      err = KSSL_ERROR_UNEXPECTED_OPCODE;
      break;
    }

    // Echo is trivial, it just echos the complete state->header back
    // including the payload item
    case KSSL_OP_PING:
    {
      response.is_payload_set = 1;
      response.payload = request.payload;
      response.payload_len = request.payload_len;
      response.is_opcode_set = 1;
      response.opcode = KSSL_OP_PONG;

      break;
    }

    // Decrypt or sign the payload using the private key
    case KSSL_OP_RSA_DECRYPT:
    case KSSL_OP_RSA_SIGN_MD5SHA1:
    case KSSL_OP_RSA_SIGN_SHA1:
    case KSSL_OP_RSA_SIGN_SHA224:
    case KSSL_OP_RSA_SIGN_SHA256:
    case KSSL_OP_RSA_SIGN_SHA384:
    case KSSL_OP_RSA_SIGN_SHA512:
    {
      unsigned int payload_size;
      int max_payload_size;
      int key_id;

      if (request.is_digest_set == 0) {
        err = KSSL_ERROR_FORMAT;
        break;
      }

      // Identify private key from request digest
      key_id = find_private_key(privates, request.digest);
      if (key_id < 0) {
        err = KSSL_ERROR_KEY_NOT_FOUND;
        break;
      }

      // Allocate buffer to hold output of private key operation
      max_payload_size = key_size(privates, key_id);
      out_payload = malloc(max_payload_size);
      if (out_payload == NULL) {
        err = KSSL_ERROR_INTERNAL;
        break;
      }

      // Operate on payload
      err = private_key_operation(privates, key_id, request.opcode,
          request.payload_len, request.payload, out_payload,
          &payload_size);
      if (err != KSSL_ERROR_NONE) {
        err = KSSL_ERROR_CRYPTO_FAILED;
        break;
      }

      response.is_payload_set = 1;
      response.payload        = out_payload;
      response.payload_len    = payload_size;
      response.is_opcode_set  = 1;
      response.opcode         = KSSL_OP_RESPONSE;

      break;
    }

    // This should not occur
  default:
    {
      err = KSSL_ERROR_BAD_OPCODE;
      break;
    }
  }

exit:
  if (err != KSSL_ERROR_NONE) {
    err = kssl_error(header->id, err, &local_resp, &local_resp_len);
  } else {

    // Create output header

    out_header.version_maj = KSSL_VERSION_MAJ;
    out_header.version_min = KSSL_VERSION_MIN;
    out_header.id          = header->id;

    // Note that the response in &local_resp is dynamically allocated
    // and needs to be freed

    err = flatten_operation(&out_header, &response, &local_resp,
        &local_resp_len);
  }

  if (out_payload != NULL) {
    free(out_payload);
  }

  if (err == KSSL_ERROR_NONE) {
    *out_response = local_resp;
    *out_response_len = local_resp_len;
  }

  return err;
}