libs/web: remove debugging code
[project/luci.git] / libs / nixio / src / tls-crypto.c
1 /*
2 * nixio - Linux I/O library for lua
3 *
4 * Copyright (C) 2009 Steven Barth <steven@midlink.org>
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include "nixio-tls.h"
20 #include <stdlib.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25
26 static int nixio_crypto_hash__init(lua_State *L, int hmac) {
27 const char *type = luaL_checkstring(L, 1);
28 nixio_hash *hash = lua_newuserdata(L, sizeof(nixio_hash));
29
30 if (!strcmp(type, "md5")) {
31 hash->type = NIXIO_HASH_MD5;
32 hash->digest_size = MD5_DIGEST_LENGTH;
33 hash->block_size = 64;
34 hash->ctx = malloc(sizeof(MD5_CTX));
35 if (!hash->ctx) {
36 return luaL_error(L, NIXIO_OOM);
37 }
38 MD5_Init((MD5_CTX*)hash->ctx);
39 hash->init = (nixio_hash_initcb)MD5_Init;
40 hash->update = (nixio_hash_updatecb)MD5_Update;
41 hash->final = (nixio_hash_finalcb)MD5_Final;
42 } else if (!strcmp(type, "sha1")) {
43 hash->type = NIXIO_HASH_SHA1;
44 hash->digest_size = SHA_DIGEST_LENGTH;
45 hash->block_size = 64;
46 hash->ctx = malloc(sizeof(SHA_CTX));
47 if (!hash->ctx) {
48 return luaL_error(L, NIXIO_OOM);
49 }
50 SHA1_Init((SHA_CTX*)hash->ctx);
51 hash->init = (nixio_hash_initcb)SHA1_Init;
52 hash->update = (nixio_hash_updatecb)SHA1_Update;
53 hash->final = (nixio_hash_finalcb)SHA1_Final;
54 } else {
55 luaL_argerror(L, 1, "supported values: md5, sha1");
56 }
57
58 luaL_getmetatable(L, NIXIO_CRYPTO_HASH_META);
59 lua_setmetatable(L, -2);
60
61 if (hmac) {
62 const char *key = luaL_checklstring(L, 2, &hash->key_size);
63 if (hash->key_size > hash->block_size) {
64 hash->update(hash->ctx, key, hash->key_size);
65 hash->final(hash->digest, hash->ctx);
66 hash->init(hash->ctx);
67 hash->key_size = hash->digest_size;
68 memcpy(hash->key, hash->digest, hash->key_size);
69 } else {
70 memcpy(hash->key, key, hash->key_size);
71 }
72
73 unsigned char pad[NIXIO_CRYPTO_BLOCK_SIZE];
74 for (uint i = 0; i < hash->block_size; i++) {
75 pad[i] = (i < hash->key_size) ? (0x36 ^ hash->key[i]) : 0x36;
76 }
77 hash->update(hash->ctx, pad, hash->block_size);
78 hash->type |= NIXIO_HMAC_BIT;
79 }
80
81 return 1;
82 }
83
84 static int nixio_crypto_hash(lua_State *L) {
85 return nixio_crypto_hash__init(L, 0);
86 }
87
88 static int nixio_crypto_hmac(lua_State *L) {
89 return nixio_crypto_hash__init(L, 1);
90 }
91
92 static int nixio_crypto_hash_update(lua_State *L) {
93 nixio_hash *hash = luaL_checkudata(L, 1, NIXIO_CRYPTO_HASH_META);
94 if (hash->type) {
95 size_t len;
96 const char *chunk = luaL_checklstring(L, 2, &len);
97 hash->update(hash->ctx, chunk, len);
98 lua_pushvalue(L, 1);
99 return 1;
100 } else {
101 return luaL_error(L, "Tried to update finalized hash object.");
102 }
103 }
104
105 static int nixio_crypto_hash_final(lua_State *L) {
106 nixio_hash *hash = luaL_checkudata(L, 1, NIXIO_CRYPTO_HASH_META);
107 if (hash->type & NIXIO_HMAC_BIT) {
108 hash->final(hash->digest, hash->ctx);
109 hash->init(hash->ctx);
110
111 unsigned char pad[NIXIO_CRYPTO_BLOCK_SIZE];
112 for (uint i = 0; i < hash->block_size; i++) {
113 pad[i] = (i < hash->key_size) ? (0x5c ^ hash->key[i]) : 0x5c;
114 }
115
116 hash->update(hash->ctx, pad, hash->block_size);
117 hash->update(hash->ctx, hash->digest, hash->digest_size);
118 }
119
120 if (hash->type) {
121 hash->type = NIXIO_HASH_NONE;
122 hash->final(hash->digest, hash->ctx);
123 free(hash->ctx);
124 }
125
126 char hashdigest[NIXIO_DIGEST_SIZE*2];
127 for (uint i=0; i < hash->digest_size; i++) {
128 hashdigest[2*i] = nixio__bin2hex[(hash->digest[i] & 0xf0) >> 4];
129 hashdigest[2*i+1] = nixio__bin2hex[(hash->digest[i] & 0x0f)];
130 }
131
132 lua_pushlstring(L, hashdigest, hash->digest_size * 2);
133 memcpy(hashdigest, hash->digest, hash->digest_size);
134 lua_pushlstring(L, hashdigest, hash->digest_size);
135
136 return 2;
137 }
138
139 static int nixio_crypto_hash__gc(lua_State *L) {
140 nixio_hash *hash = luaL_checkudata(L, 1, NIXIO_CRYPTO_HASH_META);
141 if (hash->type) {
142 hash->final(hash->digest, hash->ctx);
143 free(hash->ctx);
144 hash->type = NIXIO_HASH_NONE;
145 }
146 return 0;
147 }
148
149 static int nixio_crypto_hash__tostring(lua_State *L) {
150 nixio_hash *hash = luaL_checkudata(L, 1, NIXIO_CRYPTO_HASH_META);
151 lua_pushfstring(L, "nixio hash object: %p", hash);
152 return 1;
153 }
154
155
156 /* module table */
157 static const luaL_reg R[] = {
158 {"hash", nixio_crypto_hash},
159 {"hmac", nixio_crypto_hmac},
160 {NULL, NULL}
161 };
162
163 /* hash table */
164 static const luaL_reg M[] = {
165 {"update", nixio_crypto_hash_update},
166 {"final", nixio_crypto_hash_final},
167 {"__gc", nixio_crypto_hash__gc},
168 {"__tostring", nixio_crypto_hash__tostring},
169 {NULL, NULL}
170 };
171
172
173
174 void nixio_open_tls_crypto(lua_State *L) {
175 luaL_newmetatable(L, NIXIO_CRYPTO_HASH_META);
176 luaL_register(L, NULL, M);
177 lua_pushvalue(L, -1);
178 lua_setfield(L, -2, "__index");
179 lua_pop(L, 1);
180
181 lua_newtable(L);
182 luaL_register(L, NULL, R);
183
184 lua_setfield(L, -2, "crypto");
185 }