2 * nixio - Linux I/O library for lua
4 * Copyright (C) 2009 Steven Barth <steven@midlink.org>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "nixio-tls.h"
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
));
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
));
36 return luaL_error(L
, NIXIO_OOM
);
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
));
48 return luaL_error(L
, NIXIO_OOM
);
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
;
55 luaL_argerror(L
, 1, "supported values: md5, sha1");
58 luaL_getmetatable(L
, NIXIO_CRYPTO_HASH_META
);
59 lua_setmetatable(L
, -2);
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
);
70 memcpy(hash
->key
, key
, hash
->key_size
);
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;
77 hash
->update(hash
->ctx
, pad
, hash
->block_size
);
78 hash
->type
|= NIXIO_HMAC_BIT
;
84 static int nixio_crypto_hash(lua_State
*L
) {
85 return nixio_crypto_hash__init(L
, 0);
88 static int nixio_crypto_hmac(lua_State
*L
) {
89 return nixio_crypto_hash__init(L
, 1);
92 static int nixio_crypto_hash_update(lua_State
*L
) {
93 nixio_hash
*hash
= luaL_checkudata(L
, 1, NIXIO_CRYPTO_HASH_META
);
96 const char *chunk
= luaL_checklstring(L
, 2, &len
);
97 hash
->update(hash
->ctx
, chunk
, len
);
101 return luaL_error(L
, "Tried to update finalized hash object.");
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
);
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;
116 hash
->update(hash
->ctx
, pad
, hash
->block_size
);
117 hash
->update(hash
->ctx
, hash
->digest
, hash
->digest_size
);
121 hash
->type
= NIXIO_HASH_NONE
;
122 hash
->final(hash
->digest
, hash
->ctx
);
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)];
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
);
139 static int nixio_crypto_hash__gc(lua_State
*L
) {
140 nixio_hash
*hash
= luaL_checkudata(L
, 1, NIXIO_CRYPTO_HASH_META
);
142 hash
->final(hash
->digest
, hash
->ctx
);
144 hash
->type
= NIXIO_HASH_NONE
;
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
);
157 static const luaL_reg R
[] = {
158 {"hash", nixio_crypto_hash
},
159 {"hmac", nixio_crypto_hmac
},
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
},
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");
182 luaL_register(L
, NULL
, R
);
184 lua_setfield(L
, -2, "crypto");