Example #1
0
static int openssl_xext_data(lua_State* L)
{
  int ret = 0;
  X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension");
  if (lua_isnone(L, 2))
  {
    ASN1_STRING *s = X509_EXTENSION_get_data(x);
    s = ASN1_STRING_dup(s);
    PUSH_OBJECT(s, "openssl.asn1_string");
    return 1;
  }
  else if (lua_isstring(L, 2))
  {
    size_t size;
    const char* data = lua_tolstring(L, 2, &size);
    ASN1_STRING* s = ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
    if (ASN1_STRING_set(s, data, size) == 1)
    {
      ret = X509_EXTENSION_set_data(x, s);
    }
    ASN1_STRING_free(s);
    return openssl_pushresult(L, ret);
  }
  else
  {
    ASN1_STRING* s = CHECK_GROUP(2, ASN1_STRING, "openssl.asn1group");
    if (ASN1_STRING_type(s) == V_ASN1_OCTET_STRING)
    {
      int ret;
      ret = X509_EXTENSION_set_data(x, s);
      return openssl_pushresult(L, ret);
    }
    else
    {
      luaL_argerror(L, 2, "asn1_string type must be octet");
    }
  }
  return 0;
};
Example #2
0
static X509_ATTRIBUTE* openssl_new_xattribute(lua_State*L, X509_ATTRIBUTE** a, int idx, const char* eprefix)
{
  int arttype;
  size_t len;
  int nid;
  const char* data;

  lua_getfield(L, idx, "object");
  nid = openssl_get_nid(L, -1);
  if (nid == NID_undef)
  {
    if (eprefix)
    {
      luaL_error(L, "%s field object is invalid value", eprefix);
    }
    else
      luaL_argcheck(L, nid != NID_undef, idx, "field object is invalid value");
  }
  lua_pop(L, 1);

  lua_getfield(L, idx, "type");
  arttype = luaL_checkint(L, -1);
  if (arttype == V_ASN1_UNDEF || arttype == 0)
  {
    if (eprefix)
    {
      luaL_error(L, "%s field type is not invalid value", eprefix);
    }
    else
      luaL_argcheck(L, nid != NID_undef, idx, "field type is not invalid value");
  }
  lua_pop(L, 1);

  lua_getfield(L, idx, "value");
  if (lua_isstring(L, -1))
  {
    data = lua_tolstring(L, -1, &len);
  }
  else if (auxiliar_isgroup(L, "openssl.asn1group", -1))
  {
    ASN1_STRING* value = CHECK_GROUP(-1, ASN1_STRING, "openssl.asn1group");
    if (ASN1_STRING_type(value) != arttype)
    {
      if (eprefix)
        luaL_error(L, "%s field value not match type", eprefix);
      else
        luaL_argcheck(L, ASN1_STRING_type(value) == arttype, idx, "field value not match type");
    }
    data = (const char *)ASN1_STRING_data(value);
    len  = ASN1_STRING_length(value);
  }
  else
  {
    if (eprefix)
    {
      luaL_error(L, "%s filed value only accept string or asn1_string", eprefix);
    }
    else
      luaL_argerror(L, idx, "filed value only accept string or asn1_string");
  }
  lua_pop(L, 1);

  return X509_ATTRIBUTE_create_by_NID(a, nid, arttype, data, len);
}
Example #3
0
int pfq_getsockopt(struct socket *sock,
                int level, int optname,
                char __user * optval, int __user * optlen)
{
        struct pfq_sock *so = pfq_sk(sock->sk);
        struct pfq_rx_opt * ro;
        struct pfq_tx_opt * to;
        int len;

        if (so == NULL)
                return -EFAULT;

        ro = &so->rx_opt;
        to = &so->tx_opt;

        if (get_user(len, optlen))
                return -EFAULT;
        if (len < 0)
                return -EINVAL;

        switch(optname)
        {

        case Q_SO_GROUP_JOIN:
        {
                struct pfq_group_join group;

                if (len != sizeof(group))
                        return -EINVAL;

                if (copy_from_user(&group, optval, sizeof(group)))
                        return -EFAULT;

                if (group.class_mask == 0) {
                        pr_devel("[PFQ|%d] join error: bad class_mask(%lx)!\n", so->id, group.class_mask);
                        return -EINVAL;
                }

                if (group.gid == Q_ANY_GROUP) {

                        group.gid = pfq_join_free_group(so->id, group.class_mask, group.policy);
                        if (group.gid < 0)
                                return -EFAULT;
                        if (copy_to_user(optval, &group, len))
                                return -EFAULT;
                }
                else {
                        CHECK_GROUP(so->id, group.gid, "group join");

                        if (pfq_join_group(group.gid, so->id, group.class_mask, group.policy) < 0) {
                                pr_devel("[PFQ|%d] join error: permission denied (gid:%d)!\n", so->id, group.gid);
                                return -EACCES;
                        }
                }

                pr_devel("[PFQ|%d] join -> gid:%d class_mask:%lx\n", so->id, group.gid, group.class_mask);
        } break;

        case Q_SO_GET_ID:
        {
                if (len != sizeof(so->id))
                        return -EINVAL;
                if (copy_to_user(optval, &so->id, sizeof(so->id)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_STATUS:
        {
                int enabled;
                if (len != sizeof(int))
                        return -EINVAL;

                enabled = so->mem_addr == NULL ? 0 : 1;

                if (copy_to_user(optval, &enabled, sizeof(enabled)))
                        return -EFAULT;

        } break;

        case Q_SO_GET_STATS:
        {
                struct pfq_stats stat;
                if (len != sizeof(struct pfq_stats))
                        return -EINVAL;

                stat.recv = sparse_read(&ro->stat.recv);
                stat.lost = sparse_read(&ro->stat.lost);
                stat.drop = sparse_read(&ro->stat.drop);

                stat.sent = sparse_read(&to->stat.sent);
                stat.disc = sparse_read(&to->stat.disc);

                if (copy_to_user(optval, &stat, sizeof(stat)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_RX_TSTAMP:
        {
                if (len != sizeof(ro->tstamp))
                        return -EINVAL;
                if (copy_to_user(optval, &ro->tstamp, sizeof(ro->tstamp)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_QUEUE_MEM:
        {
                if (len != sizeof(so->mem_size))
                        return -EINVAL;

                if (copy_to_user(optval, &so->mem_size, sizeof(so->mem_size)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_RX_CAPLEN:
        {
                if (len != sizeof(ro->caplen))
                        return -EINVAL;
                if (copy_to_user(optval, &ro->caplen, sizeof(ro->caplen)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_TX_MAXLEN:
        {
                if (len != sizeof(to->maxlen))
                        return -EINVAL;
                if (copy_to_user(optval, &to->maxlen, sizeof(to->maxlen)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_RX_SLOTS:
        {
                if (len != sizeof(ro->size))
                        return -EINVAL;
                if (copy_to_user(optval, &ro->size, sizeof(ro->size)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_TX_SLOTS:
        {
                if (len != sizeof(to->size))
                        return -EINVAL;
                if (copy_to_user(optval, &to->size, sizeof(to->size)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_GROUPS:
        {
                unsigned long grps;
                if(len != sizeof(unsigned long))
                        return -EINVAL;
                grps = pfq_get_groups(so->id);
                if (copy_to_user(optval, &grps, sizeof(grps)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_GROUP_STATS:
        {
                struct pfq_group *g;
                struct pfq_stats stat;
                int gid;

                if (len != sizeof(stat))
                        return -EINVAL;

                if (copy_from_user(&stat, optval, sizeof(stat)))
                        return -EFAULT;

                gid = (int)stat.recv;

                CHECK_GROUP(so->id, gid, "group stat");

                g = pfq_get_group(gid);
                if (!g) {
                        pr_devel("[PFQ|%d] group error: invalid group id %d!\n", so->id, gid);
                        return -EFAULT;
                }

                /* check whether the group is joinable.. */

                if (!__pfq_group_access(gid, so->id, Q_POLICY_GROUP_UNDEFINED, false)) {
                        pr_devel("[PFQ|%d] group stats error: permission denied (gid:%d)!\n", so->id, gid);
                        return -EACCES;
                }

                stat.recv = sparse_read(&g->recv);
                stat.lost = sparse_read(&g->lost);
                stat.drop = sparse_read(&g->drop);

                stat.sent = 0;
                stat.disc = 0;

                if (copy_to_user(optval, &stat, sizeof(stat)))
                        return -EFAULT;
        } break;

        case Q_SO_GET_GROUP_COUNTERS:
        {
                struct pfq_group *g;
                struct pfq_counters cs;
                int i, gid;

                if (len != sizeof(cs))
                        return -EINVAL;

                if (copy_from_user(&cs, optval, sizeof(cs)))
                        return -EFAULT;

                gid = (int)cs.counter[0];

                CHECK_GROUP(so->id, gid, "group stat");

                g = pfq_get_group(gid);
                if (!g) {
                        pr_devel("[PFQ|%d] group error: invalid group id %d!\n", so->id, gid);
                        return -EFAULT;
                }

                /* check whether the group is joinable.. */

                if (!__pfq_group_access(gid, so->id, Q_POLICY_GROUP_UNDEFINED, false)) {
                        pr_devel("[PFQ|%d] group error: permission denied (gid:%d)!\n", so->id, gid);
                        return -EACCES;
                }

                for(i = 0; i < Q_MAX_COUNTERS; i++)
                {
                        cs.counter[i] = sparse_read(&g->ctx.counter[i]);
                }

                if (copy_to_user(optval, &cs, sizeof(cs)))
                        return -EFAULT;
        } break;

        default:
                return -EFAULT;
        }

        return 0;
}
Example #4
0
static X509_EXTENSION* openssl_new_xextension(lua_State*L, int idx, int v3)
{
  int nid;
  int critical = 0;
  ASN1_OCTET_STRING* value = NULL;
  X509_EXTENSION* y = NULL;

  lua_getfield(L, idx, "object");
  nid = openssl_get_nid(L, -1);
  lua_pop(L, 1);

  lua_getfield(L, idx, "critical");
  critical = lua_isnil(L, -1) ? 0 : lua_toboolean(L, -1);
  lua_pop(L, 1);

  if (nid == NID_undef)
  {
    lua_pushfstring(L, "%s is not valid object id", lua_tostring(L, -1));
    luaL_argerror(L, idx, lua_tostring(L, -1));
  }
  lua_getfield(L, idx, "value");

  luaL_argcheck(L, lua_isstring(L, -1) || auxiliar_isgroup(L, "openssl.asn1group", -1),
                1, "field value must be string or openssl.asn1group object");
  if (lua_isstring(L, -1))
  {
    size_t size;
    const char* data = lua_tolstring(L, -1, &size);
    if (v3)
    {
      const X509V3_EXT_METHOD *method = X509V3_EXT_get_nid(nid);
      if (method)
      {
        void *ext_struc = NULL;
        STACK_OF(CONF_VALUE) *nval = X509V3_parse_list(data);
        /* Now get internal extension representation based on type */
        if (method->v2i && nval)
        {
          if (sk_CONF_VALUE_num(nval) > 0)
          {
            ext_struc = method->v2i(method, NULL, nval);
          }
        }
        else if (method->s2i)
        {
          ext_struc = method->s2i(method, NULL, data);
        }
        if (nval)
          sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);

        if (ext_struc)
        {
          unsigned char *ext_der = NULL;
          int ext_len;
          /* Convert internal representation to DER */
          if (method->it)
          {
            ext_der = NULL;
            ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
            if (ext_len < 0)
            {
              ext_der = NULL;
            }
          }
          else
          {
            ext_len = method->i2d(ext_struc, NULL);
            ext_der = OPENSSL_malloc(ext_len);
            if (ext_der)
            {
              unsigned char* p = ext_der;
              method->i2d(ext_struc, &p);
            }
          }
          if (ext_der)
          {
            value = ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
            ASN1_STRING_set(value, ext_der, ext_len);
          }
          else
            value = NULL;

          if (method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
          else method->ext_free(ext_struc);
        }
      }
    }
    else
    {
      value = ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
      ASN1_STRING_set(value, data, size);
    }
    if (value)
    {
      y = X509_EXTENSION_create_by_NID(NULL, nid, critical, value);
      ASN1_STRING_free(value);
      return y;
    }
    else
    {
      luaL_error(L, "don't support object(%s) with value (%s)", OBJ_nid2ln(nid), data);
      return NULL;
    }
  }
  else
  {
    value = CHECK_GROUP(-1, ASN1_STRING, "openssl.asn1group");
    y = X509_EXTENSION_create_by_NID(NULL, nid, critical, value);
    lua_pop(L, 1);
    return y;
  }
}