nginx

Paddy 2015-06-30 Parent:68478c1bddde

1:ac9c19126939 Go to Latest

nginx/jwt-lib/resty/hmac.lua

Make nginx kubernetes-ready. We had to update to use a ubuntu-based image to build nginx into, because (and I kid you not) alpine linux straight-up ignores your resolv.conf file, meaning any attempt to use it with kubernetes DNS is doomed to fail. Who thought this was a good idea? So we're using a bloated image instead. Oh well. We also are running a wrapper script instead of nginx directly, so we can inject the JWT_SECRET environment variable based on a kubernetes secret file. We define the secret file (using a placeholder secret, obvs) so that future-Paddy can remember what the hell it looks like, when he inevitably loses the file and needs to sin up a new cluster. Or whatever. Finally, we updated the token expiration error message to be in an errors array, as God (and our API conventions) intended.

History
2 local str_util = require "resty.string"
3 local ffi = require "ffi"
4 local ffi_new = ffi.new
5 local ffi_str = ffi.string
6 local ffi_gc = ffi.gc
7 local C = ffi.C
8 local setmetatable = setmetatable
9 local error = error
12 local _M = { _VERSION = '0.01' }
14 local mt = { __index = _M }
17 ffi.cdef[[
18 typedef struct engine_st ENGINE;
19 typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
20 typedef struct env_md_ctx_st EVP_MD_CTX;
21 typedef struct env_md_st EVP_MD;
23 struct env_md_ctx_st
24 {
25 const EVP_MD *digest;
26 ENGINE *engine;
27 unsigned long flags;
28 void *md_data;
29 EVP_PKEY_CTX *pctx;
30 int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
31 };
33 struct env_md_st
34 {
35 int type;
36 int pkey_type;
37 int md_size;
38 unsigned long flags;
39 int (*init)(EVP_MD_CTX *ctx);
40 int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
41 int (*final)(EVP_MD_CTX *ctx,unsigned char *md);
42 int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from);
43 int (*cleanup)(EVP_MD_CTX *ctx);
45 int (*sign)(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, void *key);
46 int (*verify)(int type, const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, void *key);
47 int required_pkey_type[5];
48 int block_size;
49 int ctx_size;
50 int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
51 };
53 typedef struct hmac_ctx_st
54 {
55 const EVP_MD *md;
56 EVP_MD_CTX md_ctx;
57 EVP_MD_CTX i_ctx;
58 EVP_MD_CTX o_ctx;
59 unsigned int key_length;
60 unsigned char key[128];
61 } HMAC_CTX;
63 void HMAC_CTX_init(HMAC_CTX *ctx);
64 void HMAC_CTX_cleanup(HMAC_CTX *ctx);
66 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,const EVP_MD *md, ENGINE *impl);
67 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
68 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
70 const EVP_MD *EVP_md5(void);
71 const EVP_MD *EVP_sha1(void);
72 const EVP_MD *EVP_sha256(void);
73 const EVP_MD *EVP_sha512(void);
74 ]]
76 local buf = ffi_new("unsigned char[64]")
77 local res_len = ffi_new("unsigned int[1]")
78 local ctx_ptr_type = ffi.typeof("HMAC_CTX[1]")
79 local hashes = {
80 MD5 = C.EVP_md5(),
81 SHA1 = C.EVP_sha1(),
82 SHA256 = C.EVP_sha256(),
83 SHA512 = C.EVP_sha512()
84 }
87 _M.ALGOS = hashes
90 function _M.new(self, key, hash_algo)
91 local ctx = ffi_new(ctx_ptr_type)
93 C.HMAC_CTX_init(ctx)
95 local _hash_algo = hash_algo or hashes.md5
97 if C.HMAC_Init_ex(ctx, key, #key, _hash_algo, nil) == 0 then
98 return nil
99 end
101 ffi_gc(ctx, C.HMAC_CTX_cleanup)
103 return setmetatable({ _ctx = ctx }, mt)
104 end
107 function _M.update(self, s)
108 return C.HMAC_Update(self._ctx, s, #s) == 1
109 end
112 function _M.final(self, s, hex_output)
114 if s ~= nil then
115 if C.HMAC_Update(self._ctx, s, #s) == 0 then
116 return nil
117 end
118 end
120 if C.HMAC_Final(self._ctx, buf, res_len) == 1 then
121 if hex_output == true then
122 return str_util.to_hex(ffi_str(buf, res_len[0]))
123 end
124 return ffi_str(buf, res_len[0])
125 end
127 return nil
128 end
131 function _M.reset(self)
132 return C.HMAC_Init_ex(self._ctx, nil, 0, nil, nil) == 1
133 end
135 return _M