示例#1
0
const EVP_MD* get_digest(lua_State* L, int idx, const char* def_alg)
{
  const EVP_MD* md = NULL;
  switch (lua_type(L, idx))
  {
  case LUA_TSTRING:
    md = EVP_get_digestbyname(lua_tostring(L, idx));
    break;
  case LUA_TNUMBER:
    md = EVP_get_digestbynid(lua_tointeger(L, idx));
    break;
  case LUA_TUSERDATA:
    if (auxiliar_getclassudata(L, "openssl.asn1_object", idx))
      md = EVP_get_digestbyobj(CHECK_OBJECT(idx, ASN1_OBJECT, "openssl.asn1_object"));
    else if (auxiliar_getclassudata(L, "openssl.evp_digest", idx))
      md = CHECK_OBJECT(idx, EVP_MD, "openssl.evp_digest");
    break;
  case LUA_TNONE:
  case LUA_TNIL:
    if (def_alg != NULL)
      md = EVP_get_digestbyname(def_alg);
    break;
  }

  if (md==NULL)
  {
    luaL_argerror(L, idx, "must be a string, NID number or asn1_object identity digest method");
  }

  return md;
}
示例#2
0
const EVP_CIPHER* get_cipher(lua_State*L, int idx, const char* def_alg)
{
  const EVP_CIPHER* cipher = NULL;

  switch (lua_type(L, idx))
  {
  case LUA_TSTRING:
    cipher = EVP_get_cipherbyname(lua_tostring(L, idx));
    break;
  case LUA_TNUMBER:
    cipher = EVP_get_cipherbynid(lua_tointeger(L, idx));
    break;
  case LUA_TUSERDATA:
    if (auxiliar_getclassudata(L, "openssl.asn1_object", idx))
      cipher = EVP_get_cipherbyobj(CHECK_OBJECT(idx, ASN1_OBJECT, "openssl.asn1_object"));
    else if (auxiliar_getclassudata(L, "openssl.evp_cipher", idx))
      cipher = CHECK_OBJECT(idx, EVP_CIPHER, "openssl.evp_cipher");
    break;
  case LUA_TNONE:
  case LUA_TNIL:
    if (def_alg != NULL)
      cipher = EVP_get_cipherbyname(def_alg);
    break;
  }

  if (cipher==NULL)
    luaL_argerror(L, idx, "must be a string, NID number or asn1_object identity cipher method");

  return cipher;
}
示例#3
0
/***
create or generate a new x509_req object.
Note if not give evp_pkey, will create a new x509_req object,or will generate a signed x509_req object.
@function new
@tparam[opt] x509_name subject subject name set to x509_req
@tparam[opt] stack_of_x509_extension extensions add to x509_req
@tparam[opt] stack_of_x509_attribute attributes add to x509_req
@tparam[opt] evp_pkey pkey private key sign the x509_req, and set as public key
@tparam[opt='sha1WithRSAEncryption'] evp_digest|string md_alg,  only used when pkey exist, and should fellow pkey
@treturn x509_req certificate sign request object
@see x509_req
*/
static LUA_FUNCTION(openssl_csr_new)
{
  X509_REQ *csr = X509_REQ_new();
  int i;
  int n = lua_gettop(L);
  int ret = X509_REQ_set_version(csr, 0L);

  for (i = 1; ret == 1 && i <= n; i++)
  {
    luaL_argcheck(L,
                  auxiliar_getclassudata(L, "openssl.x509_name", i) ||
                  auxiliar_getclassudata(L, "openssl.evp_pkey", i),
                  i, "must be x509_name or evp_pkey");
    if (auxiliar_getclassudata(L, "openssl.x509_name", i))
    {
      X509_NAME * subject = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name");
      ret = X509_REQ_set_subject_name(csr, subject);
    }
    if (auxiliar_getclassudata(L, "openssl.evp_pkey", i))
    {
      EVP_PKEY *pkey;
      const EVP_MD *md;
      luaL_argcheck(L, i == n || i == n - 1, i, "must is evp_pkey object");

      pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey");

      if (i == n - 1)
        md = get_digest(L, n, NULL);
      else
        md = EVP_get_digestbyname("sha256");

      ret = X509_REQ_set_pubkey(csr, pkey);
      if (ret == 1)
      {
        ret = X509_REQ_sign(csr, pkey, md);
        if (ret > 0)
          ret = 1;
      }
      break;
    }
  };

  if (ret == 1)
    PUSH_OBJECT(csr, "openssl.x509_req");
  else
  {
    X509_REQ_free(csr);
    return openssl_pushresult(L, ret);
  }
  return 1;
}
示例#4
0
/***
add attribute to x509_req object
@function attribute
@tparam x509_attribute attribute attribute to add
@treturn boolean result
*/
static LUA_FUNCTION(openssl_csr_attribute)
{
  X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  if (auxiliar_getclassudata(L, "openssl.x509_attribute", 2))
  {
    X509_ATTRIBUTE *attr = CHECK_OBJECT(2, X509_ATTRIBUTE, "openssl.x509_attribute");
    int ret = X509_REQ_add1_attr(csr, attr);
    return openssl_pushresult(L, ret);
  }
  else if (lua_isnumber(L, 2))
  {
    int loc = luaL_checkint(L, 2);
    X509_ATTRIBUTE *attr = NULL;
    if (lua_isnone(L, 3))
    {
      attr = X509_REQ_get_attr(csr, loc);
      attr = X509_ATTRIBUTE_dup(attr);
    }
    else if (lua_isnil(L, 3))
    {
      attr = X509_REQ_delete_attr(csr, loc);
    }
    if (attr)
    {
      PUSH_OBJECT(attr, "openssl.x509_attribute");
    }
    else
      lua_pushnil(L);
    return 1;
  }
  else if (lua_istable(L, 2))
  {
    int i;
    int ret = 1;
    int n = lua_rawlen(L, 2);
    for (i = 1; ret == 1 && i <= n; i++)
    {
      X509_ATTRIBUTE *attr;
      lua_rawgeti(L, 2, i);
      attr = NULL;
      if (lua_istable(L, -1))
      {
        attr = openssl_new_xattribute(L, &attr, -1, NULL);
        ret = X509_REQ_add1_attr(csr, attr);
        X509_ATTRIBUTE_free(attr);
      }
      else
      {
        attr = CHECK_OBJECT(-1, X509_ATTRIBUTE, "openssl.x509_attribute");
        ret = X509_REQ_add1_attr(csr, attr);
      }
      lua_pop(L, 1);
    }
    openssl_pushresult(L, ret);
    return 1;
  }

  return 0;
}
示例#5
0
/*-------------------------------------------------------------------------*\
* Return userdata pointer if object belongs to a given class, abort with 
* error otherwise
\*-------------------------------------------------------------------------*/
void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) {
    void *data = auxiliar_getclassudata(L, classname, objidx);
    if (!data) {
        char msg[45];
        sprintf(msg, "%.35s expected", classname);
        luaL_argerror(L, objidx, msg);
    }
    return data;
}
示例#6
0
BIO* load_bio_object(lua_State* L, int idx)
{
  BIO* bio = NULL;
  if (lua_isstring(L, idx))
  {
    size_t l = 0;
    const char* ctx = lua_tolstring(L, idx, &l);
    /* read only */
    bio = (BIO*)BIO_new_mem_buf((void*)ctx, l);
  }
  else if (auxiliar_getclassudata(L, "openssl.bio", idx))
  {
    bio = CHECK_OBJECT(idx, BIO, "openssl.bio");
    BIO_up_ref(bio);
  }
  else
    luaL_argerror(L, idx, "only support string or openssl.bio");
  return bio;
}
示例#7
0
/***
sign x509_req object

@function sign
@tparam evp_pkey pkey private key which to sign x509_req object
@tparam number|string|evp_md md message digest alg used to sign
@treturn boolean result true for suceess
*/
static LUA_FUNCTION(openssl_csr_sign)
{
  X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr);
  if (auxiliar_getclassudata(L, "openssl.evp_pkey", 2))
  {
    EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey");
    const EVP_MD* md = get_digest(L, 3, "sha256");
    int ret = 1;
    if (pubkey == NULL)
    {
      BIO* bio = BIO_new(BIO_s_mem());
      if ((ret = i2d_PUBKEY_bio(bio, pkey)) == 1)
      {
        pubkey = d2i_PUBKEY_bio(bio, NULL);
        if (pubkey)
        {
          ret = X509_REQ_set_pubkey(csr, pubkey);
          EVP_PKEY_free(pubkey);
        }
        else
        {
          ret = 0;
        }
      }
      BIO_free(bio);
    }
    else
    {
      EVP_PKEY_free(pubkey);
    }
    if (ret == 1)
      ret = X509_REQ_sign(csr, pkey, md);
    return openssl_pushresult(L, ret);
  }
  else if (lua_isstring(L, 2))
  {
    size_t siglen;
    unsigned char* sigdata = (unsigned char*)luaL_checklstring(L, 2, &siglen);
    const EVP_MD* md = get_digest(L, 3, NULL);
    ASN1_BIT_STRING *sig = NULL;
    X509_ALGOR *alg = NULL;

    luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!");

    X509_REQ_get0_signature(csr, (const ASN1_BIT_STRING **)&sig, (const X509_ALGOR **)&alg);
    /* (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) ? V_ASN1_NULL : V_ASN1_UNDEF, */
    X509_ALGOR_set0((X509_ALGOR *)alg, OBJ_nid2obj(EVP_MD_pkey_type(md)), V_ASN1_NULL, NULL);

    ASN1_BIT_STRING_set((ASN1_BIT_STRING *)sig, sigdata, siglen);
    /*
    * In the interests of compatibility, I'll make sure that the bit string
    * has a 'not-used bits' value of 0
    */
    sig->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
    sig->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    lua_pushboolean(L, 1);
    return 1;
  }
  else
  {
    int inl;
    unsigned char* tosign = NULL;
    luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!");

    inl = i2d_re_X509_REQ_tbs(csr, &tosign);
    if (inl > 0 && tosign)
    {
      lua_pushlstring(L, (const char*)tosign, inl);
      OPENSSL_free(tosign);
      return 1;
    }
    return openssl_pushresult(L, 0);
  }
}