You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2020/05/08 21:23:11 UTC

[trafficserver] branch 9.0.x updated: Lua Plugin - Extend the crypto API with SHA-256 and HMAC functions.

This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 57cc524  Lua Plugin - Extend the crypto API with SHA-256 and HMAC functions.
57cc524 is described below

commit 57cc5247fdf930fe913777e158cc09dbe5d9318b
Author: Peter Chou <pb...@labs.att.com>
AuthorDate: Sat Apr 18 00:06:34 2020 -0700

    Lua Plugin - Extend the crypto API with SHA-256 and HMAC functions.
    
    Adds the following functions to the Lua plugin crypto API: ts.sha256(),
    ts.sha256_bin(), ts.hmac_md5(), ts.hmac_sha1(), and ts.hmac_sha256().
    
    (cherry picked from commit 45d9e7454ab121cf99ca460f62d4bcab8688c40e)
---
 doc/admin-guide/plugins/lua.en.rst | 119 +++++++++++++++++
 plugins/lua/ts_lua_crypto.c        | 264 ++++++++++++++++++++++++++++++++++++-
 plugins/lua/ts_lua_string.c        |  38 ++++++
 plugins/lua/ts_lua_string.h        |   1 +
 4 files changed, 418 insertions(+), 4 deletions(-)

diff --git a/doc/admin-guide/plugins/lua.en.rst b/doc/admin-guide/plugins/lua.en.rst
index 3200f0a..a76cf44 100644
--- a/doc/admin-guide/plugins/lua.en.rst
+++ b/doc/admin-guide/plugins/lua.en.rst
@@ -1704,6 +1704,125 @@ Here is an example:
 
 `TOP <#ts-lua-plugin>`_
 
+ts.sha256
+---------
+**syntax:** *digest = ts.sha256(str)*
+
+**context:** global
+
+**description:** Returns the hexadecimal representation of the SHA-256 digest of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        uri = ts.client_request.get_uri()
+        print(uri)
+        print(ts.sha256(uri))
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.sha256_bin
+-------------
+**syntax:** *digest = ts.sha256_bin(str)*
+
+**context:** global
+
+**description:** Returns the binary form of the SHA-256 digest of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        uri = ts.client_request.get_uri()
+        bin = ts.sha256_bin(uri)
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.hmac_md5
+-----------
+**syntax:** *digest = ts.hmac_md5(key, str)*
+
+**context:** global
+
+**description:** Returns the hexadecimal representation of the HMAC of the ``str`` argument.
+
+The message digest function used is MD5.
+
+The key value used is contained in the ``key`` argument. This should be a hexadecimal representation of the key value.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        key = "012345"
+        uri = ts.client_request.get_uri()
+        print(uri)
+        print(ts.hmac_md5(key, uri))
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.hmac_sha1
+------------
+**syntax:** *digest = ts.hmac_sha1(key, str)*
+
+**context:** global
+
+**description:** Returns the hexadecimal representation of the HMAC of the ``str`` argument.
+
+The message digest function used is SHA-1.
+
+The key value used is contained in the ``key`` argument. This should be a hexadecimal representation of the key value.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        key = "012345"
+        uri = ts.client_request.get_uri()
+        print(uri)
+        print(ts.hmac_sha1(key, uri))
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.hmac_sha256
+--------------
+**syntax:** *digest = ts.hmac_sha256(key, str)*
+
+**context:** global
+
+**description:** Returns the hexadecimal representation of the HMAC of the ``str`` argument.
+
+The message digest function used is SHA-256.
+
+The key value used is contained in the ``key`` argument. This should be a hexadecimal representation of the key value.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        key = "012345"
+        uri = ts.client_request.get_uri()
+        print(uri)
+        print(ts.hmac_sha256(key, uri))
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
 ts.server_request.server_addr.get_ip
 ------------------------------------
 **syntax:** *ts.server_request.server_addr.get_ip()*
diff --git a/plugins/lua/ts_lua_crypto.c b/plugins/lua/ts_lua_crypto.c
index 7637183..b1e02d7 100644
--- a/plugins/lua/ts_lua_crypto.c
+++ b/plugins/lua/ts_lua_crypto.c
@@ -18,11 +18,13 @@
 
 #include <openssl/md5.h>
 #include <openssl/sha.h>
+#include <openssl/hmac.h>
 #include "ts_lua_string.h"
 #include "ts_lua_util.h"
 
 #define TS_LUA_MD5_DIGEST_LENGTH 16
-#define TS_LUA_SHA_DIGEST_LENGTH 20
+#define TS_LUA_SHA1_DIGEST_LENGTH 20
+#define TS_LUA_SHA256_DIGEST_LENGTH 32
 
 static int ts_lua_md5(lua_State *L);
 static int ts_lua_md5_bin(lua_State *L);
@@ -30,6 +32,13 @@ static int ts_lua_md5_bin(lua_State *L);
 static int ts_lua_sha1(lua_State *L);
 static int ts_lua_sha1_bin(lua_State *L);
 
+static int ts_lua_sha256(lua_State *L);
+static int ts_lua_sha256_bin(lua_State *L);
+
+static int ts_lua_hmac_md5(lua_State *L);
+static int ts_lua_hmac_sha1(lua_State *L);
+static int ts_lua_hmac_sha256(lua_State *L);
+
 static int ts_lua_base64_encode(lua_State *L);
 static int ts_lua_base64_decode(lua_State *L);
 
@@ -47,7 +56,7 @@ ts_lua_inject_crypto_api(lua_State *L)
   lua_pushcfunction(L, ts_lua_md5_bin);
   lua_setfield(L, -2, "md5_bin");
 
-  /* ts.sha1_bin(...) */
+  /* ts.sha1(...) */
   lua_pushcfunction(L, ts_lua_sha1);
   lua_setfield(L, -2, "sha1");
 
@@ -55,6 +64,26 @@ ts_lua_inject_crypto_api(lua_State *L)
   lua_pushcfunction(L, ts_lua_sha1_bin);
   lua_setfield(L, -2, "sha1_bin");
 
+  /* ts.sha256(...) */
+  lua_pushcfunction(L, ts_lua_sha256);
+  lua_setfield(L, -2, "sha256");
+
+  /* ts.sha256_bin(...) */
+  lua_pushcfunction(L, ts_lua_sha256_bin);
+  lua_setfield(L, -2, "sha256_bin");
+
+  /* ts.hmac_md5(...) */
+  lua_pushcfunction(L, ts_lua_hmac_md5);
+  lua_setfield(L, -2, "hmac_md5");
+
+  /* ts.hmac_sha1(...) */
+  lua_pushcfunction(L, ts_lua_hmac_sha1);
+  lua_setfield(L, -2, "hmac_sha1");
+
+  /* ts.hmac_sha256(...) */
+  lua_pushcfunction(L, ts_lua_hmac_sha256);
+  lua_setfield(L, -2, "hmac_sha256");
+
   /* ts.base64_encode(...) */
   lua_pushcfunction(L, ts_lua_base64_encode);
   lua_setfield(L, -2, "base64_encode");
@@ -142,7 +171,7 @@ ts_lua_sha1(lua_State *L)
   size_t slen;
 
   SHA_CTX sha;
-  u_char sha_buf[TS_LUA_SHA_DIGEST_LENGTH];
+  u_char sha_buf[TS_LUA_SHA1_DIGEST_LENGTH];
   u_char hex_buf[2 * sizeof(sha_buf)];
 
   if (lua_gettop(L) != 1) {
@@ -174,7 +203,7 @@ ts_lua_sha1_bin(lua_State *L)
   size_t slen;
 
   SHA_CTX sha;
-  u_char sha_buf[TS_LUA_SHA_DIGEST_LENGTH];
+  u_char sha_buf[TS_LUA_SHA1_DIGEST_LENGTH];
 
   if (lua_gettop(L) != 1) {
     return luaL_error(L, "expecting one argument");
@@ -198,6 +227,233 @@ ts_lua_sha1_bin(lua_State *L)
 }
 
 static int
+ts_lua_sha256(lua_State *L)
+{
+  u_char *src;
+  size_t slen;
+
+  SHA256_CTX sha;
+  u_char sha_buf[TS_LUA_SHA256_DIGEST_LENGTH];
+  u_char hex_buf[2 * sizeof(sha_buf)];
+
+  if (lua_gettop(L) != 1) {
+    return luaL_error(L, "expecting one argument");
+  }
+
+  if (lua_isnil(L, 1)) {
+    src  = (u_char *)"";
+    slen = 0;
+
+  } else {
+    src = (u_char *)luaL_checklstring(L, 1, &slen);
+  }
+
+  SHA256_Init(&sha);
+  SHA256_Update(&sha, src, slen);
+  SHA256_Final(sha_buf, &sha);
+
+  ts_lua_hex_dump(hex_buf, sha_buf, sizeof(sha_buf));
+  lua_pushlstring(L, (char *)hex_buf, sizeof(hex_buf));
+
+  return 1;
+}
+
+static int
+ts_lua_sha256_bin(lua_State *L)
+{
+  u_char *src;
+  size_t slen;
+
+  SHA256_CTX sha;
+  u_char sha_buf[TS_LUA_SHA256_DIGEST_LENGTH];
+
+  if (lua_gettop(L) != 1) {
+    return luaL_error(L, "expecting one argument");
+  }
+
+  if (lua_isnil(L, 1)) {
+    src  = (u_char *)"";
+    slen = 0;
+
+  } else {
+    src = (u_char *)luaL_checklstring(L, 1, &slen);
+  }
+
+  SHA256_Init(&sha);
+  SHA256_Update(&sha, src, slen);
+  SHA256_Final(sha_buf, &sha);
+
+  lua_pushlstring(L, (char *)sha_buf, sizeof(sha_buf));
+
+  return 1;
+}
+
+static int
+ts_lua_hmac_md5(lua_State *L)
+{
+  u_char *key;
+  u_char *src;
+  size_t klen;
+  size_t slen;
+
+  unsigned char *key_bin;
+  unsigned int key_bin_len;
+
+  u_char sha_buf[TS_LUA_MD5_DIGEST_LENGTH];
+  u_char hex_buf[2 * sizeof(sha_buf)];
+  unsigned int output_length;
+
+  if (lua_gettop(L) != 2) {
+    return luaL_error(L, "expecting two arguments");
+  }
+
+  if (lua_isnil(L, 1)) {
+    key  = (u_char *)"";
+    klen = 0;
+
+  } else {
+    key = (u_char *)luaL_checklstring(L, 1, &klen);
+  }
+
+  if (lua_isnil(L, 2)) {
+    src  = (u_char *)"";
+    slen = 0;
+
+  } else {
+    src = (u_char *)luaL_checklstring(L, 2, &slen);
+  }
+
+  key_bin = TSmalloc((int)((klen / 2) + 1));
+  if (key_bin == NULL) {
+    TSDebug(TS_LUA_DEBUG_TAG, "unable to allocate buffer for hex to binary conversion");
+    return luaL_error(L, "unable to allocate buffer for hex to binary conversion");
+  }
+  if (ts_lua_hex_to_bin(key_bin, key, klen) == NULL) {
+    TSfree(key_bin);
+    return luaL_error(L, "hex to binary conversion failed");
+  }
+  key_bin_len = klen / 2;
+
+  HMAC(EVP_md5(), key_bin, key_bin_len, src, slen, sha_buf, &output_length);
+
+  ts_lua_hex_dump(hex_buf, sha_buf, sizeof(sha_buf));
+  lua_pushlstring(L, (char *)hex_buf, sizeof(hex_buf));
+
+  TSfree(key_bin);
+  return 1;
+}
+
+static int
+ts_lua_hmac_sha1(lua_State *L)
+{
+  u_char *key;
+  u_char *src;
+  size_t klen;
+  size_t slen;
+
+  unsigned char *key_bin;
+  unsigned int key_bin_len;
+
+  u_char sha_buf[TS_LUA_SHA1_DIGEST_LENGTH];
+  u_char hex_buf[2 * sizeof(sha_buf)];
+  unsigned int output_length;
+
+  if (lua_gettop(L) != 2) {
+    return luaL_error(L, "expecting two arguments");
+  }
+
+  if (lua_isnil(L, 1)) {
+    key  = (u_char *)"";
+    klen = 0;
+
+  } else {
+    key = (u_char *)luaL_checklstring(L, 1, &klen);
+  }
+
+  if (lua_isnil(L, 2)) {
+    src  = (u_char *)"";
+    slen = 0;
+
+  } else {
+    src = (u_char *)luaL_checklstring(L, 2, &slen);
+  }
+
+  key_bin = TSmalloc((int)((klen / 2) + 1));
+  if (key_bin == NULL) {
+    TSDebug(TS_LUA_DEBUG_TAG, "unable to allocate buffer for hex to binary conversion");
+    return luaL_error(L, "unable to allocate buffer for hex to binary conversion");
+  }
+  if (ts_lua_hex_to_bin(key_bin, key, klen) == NULL) {
+    TSfree(key_bin);
+    return luaL_error(L, "hex to binary conversion failed");
+  }
+  key_bin_len = klen / 2;
+
+  HMAC(EVP_sha1(), key_bin, key_bin_len, src, slen, sha_buf, &output_length);
+
+  ts_lua_hex_dump(hex_buf, sha_buf, sizeof(sha_buf));
+  lua_pushlstring(L, (char *)hex_buf, sizeof(hex_buf));
+
+  TSfree(key_bin);
+  return 1;
+}
+
+static int
+ts_lua_hmac_sha256(lua_State *L)
+{
+  u_char *key;
+  u_char *src;
+  size_t klen;
+  size_t slen;
+
+  unsigned char *key_bin;
+  unsigned int key_bin_len;
+
+  u_char sha_buf[TS_LUA_SHA256_DIGEST_LENGTH];
+  u_char hex_buf[2 * sizeof(sha_buf)];
+  unsigned int output_length;
+
+  if (lua_gettop(L) != 2) {
+    return luaL_error(L, "expecting two arguments");
+  }
+
+  if (lua_isnil(L, 1)) {
+    key  = (u_char *)"";
+    klen = 0;
+
+  } else {
+    key = (u_char *)luaL_checklstring(L, 1, &klen);
+  }
+
+  if (lua_isnil(L, 2)) {
+    src  = (u_char *)"";
+    slen = 0;
+
+  } else {
+    src = (u_char *)luaL_checklstring(L, 2, &slen);
+  }
+
+  key_bin = TSmalloc((int)((klen / 2) + 1));
+  if (key_bin == NULL) {
+    TSDebug(TS_LUA_DEBUG_TAG, "unable to allocate buffer for hex to binary conversion");
+    return luaL_error(L, "unable to allocate buffer for hex to binary conversion");
+  }
+  if (ts_lua_hex_to_bin(key_bin, key, klen) == NULL) {
+    TSfree(key_bin);
+    return luaL_error(L, "hex to binary conversion failed");
+  }
+  key_bin_len = klen / 2;
+
+  HMAC(EVP_sha256(), key_bin, key_bin_len, src, slen, sha_buf, &output_length);
+
+  ts_lua_hex_dump(hex_buf, sha_buf, sizeof(sha_buf));
+  lua_pushlstring(L, (char *)hex_buf, sizeof(hex_buf));
+
+  TSfree(key_bin);
+  return 1;
+}
+
+static int
 ts_lua_base64_encode(lua_State *L)
 {
   u_char *src;
diff --git a/plugins/lua/ts_lua_string.c b/plugins/lua/ts_lua_string.c
index 76747a6..727b5a3 100644
--- a/plugins/lua/ts_lua_string.c
+++ b/plugins/lua/ts_lua_string.c
@@ -17,6 +17,7 @@
 */
 
 #include "ts_lua_string.h"
+#include "ts_lua_util.h"
 
 u_char *
 ts_lua_hex_dump(u_char *dst, u_char *src, size_t len)
@@ -30,3 +31,40 @@ ts_lua_hex_dump(u_char *dst, u_char *src, size_t len)
 
   return dst;
 }
+
+unsigned char
+hex_to_int(unsigned char c)
+{
+  if (c >= '0' && c <= '9') {
+    return (c - '0');
+  }
+  if (c >= 'A' && c <= 'F') {
+    return (c - 'A' + 10);
+  }
+  if (c >= 'a' && c <= 'f') {
+    return (c - 'a' + 10);
+  }
+  return 255;
+}
+
+u_char *
+ts_lua_hex_to_bin(u_char *dst, u_char *src, size_t len)
+{
+  if (len % 2 != 0) {
+    TSDebug(TS_LUA_DEBUG_TAG, "ts_lua_hex_to_bin(): not an even number of hex digits");
+    return NULL;
+  }
+
+  for (unsigned int x = 0; x < len; x += 2) {
+    unsigned char a = hex_to_int(src[x]);
+    unsigned char b = hex_to_int(src[x + 1]);
+    if (a == 255 || b == 255) {
+      TSDebug(TS_LUA_DEBUG_TAG, "ts_lua_hex_to_bin(): failure in hex to binary conversion");
+      return NULL;
+    }
+    unsigned char result = (a << 4) + b;
+    dst[x / 2]           = result;
+  }
+
+  return dst;
+}
diff --git a/plugins/lua/ts_lua_string.h b/plugins/lua/ts_lua_string.h
index 35c5e65..bc36a6c 100644
--- a/plugins/lua/ts_lua_string.h
+++ b/plugins/lua/ts_lua_string.h
@@ -24,3 +24,4 @@
 #include <inttypes.h>
 
 u_char *ts_lua_hex_dump(u_char *dst, u_char *src, size_t len);
+u_char *ts_lua_hex_to_bin(u_char *dst, u_char *src, size_t len);