Comparison

util-src/crypto.c @ 12697:916871447b2f

util.crypto: Add support for RSA signatures (PKCS1-v1.5 + PSS) These are used by the RS*** and PS*** family of JOSE algorithms (e.g. in JWTs)
author Matthew Wild <mwild1@gmail.com>
date Sat, 02 Jul 2022 11:50:56 +0100
parent 12693:7c5afbdcbc77
child 12698:999663b4e39d
comparison
equal deleted inserted replaced
12696:27a72982e331 12697:916871447b2f
45 MANAGED_POINTER_ALLOCATOR(new_managed_BIO_s_mem, BIO*, new_memory_BIO, BIO_free) 45 MANAGED_POINTER_ALLOCATOR(new_managed_BIO_s_mem, BIO*, new_memory_BIO, BIO_free)
46 MANAGED_POINTER_ALLOCATOR(new_managed_EVP_CIPHER_CTX, EVP_CIPHER_CTX*, EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_free) 46 MANAGED_POINTER_ALLOCATOR(new_managed_EVP_CIPHER_CTX, EVP_CIPHER_CTX*, EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_free)
47 47
48 static EVP_PKEY* pkey_from_arg(lua_State *L, int idx, const int type, const int require_private) { 48 static EVP_PKEY* pkey_from_arg(lua_State *L, int idx, const int type, const int require_private) {
49 EVP_PKEY *pkey = *(EVP_PKEY**)luaL_checkudata(L, idx, PKEY_MT_TAG); 49 EVP_PKEY *pkey = *(EVP_PKEY**)luaL_checkudata(L, idx, PKEY_MT_TAG);
50 int got_type;
50 if(type || require_private) { 51 if(type || require_private) {
51 lua_getuservalue(L, idx); 52 lua_getuservalue(L, idx);
52 if(type != 0) { 53 if(type != 0) {
53 lua_getfield(L, -1, "type"); 54 lua_getfield(L, -1, "type");
54 if(lua_tointeger(L, -1) != type) { 55 got_type = lua_tointeger(L, -1);
56 if(got_type != type) {
55 luaL_argerror(L, idx, "unexpected key type"); 57 luaL_argerror(L, idx, "unexpected key type");
56 } 58 }
57 lua_pop(L, 1); 59 lua_pop(L, 1);
58 } 60 }
59 if(require_private != 0) { 61 if(require_private != 0) {
81 lua_pushstring(L, OBJ_nid2sn(key_type)); 83 lua_pushstring(L, OBJ_nid2sn(key_type));
82 return 1; 84 return 1;
83 } 85 }
84 86
85 static int base_evp_sign(lua_State *L, const int key_type, const EVP_MD *digest_type) { 87 static int base_evp_sign(lua_State *L, const int key_type, const EVP_MD *digest_type) {
86 EVP_PKEY *pkey = pkey_from_arg(L, 1, key_type, 1); 88 EVP_PKEY *pkey = pkey_from_arg(L, 1, (key_type!=NID_rsassaPss)?key_type:NID_rsaEncryption, 1);
87 luaL_Buffer sigbuf; 89 luaL_Buffer sigbuf;
88 90
89 size_t msg_len; 91 size_t msg_len;
90 const unsigned char* msg = (unsigned char*)lua_tolstring(L, 2, &msg_len); 92 const unsigned char* msg = (unsigned char*)lua_tolstring(L, 2, &msg_len);
91 93
94 EVP_MD_CTX *md_ctx = new_managed_EVP_MD_CTX(L); 96 EVP_MD_CTX *md_ctx = new_managed_EVP_MD_CTX(L);
95 97
96 if(EVP_DigestSignInit(md_ctx, NULL, digest_type, NULL, pkey) != 1) { 98 if(EVP_DigestSignInit(md_ctx, NULL, digest_type, NULL, pkey) != 1) {
97 lua_pushnil(L); 99 lua_pushnil(L);
98 return 1; 100 return 1;
101 }
102 if(key_type == NID_rsassaPss) {
103 EVP_PKEY_CTX_set_rsa_padding(EVP_MD_CTX_pkey_ctx(md_ctx), RSA_PKCS1_PSS_PADDING);
99 } 104 }
100 if(EVP_DigestSign(md_ctx, NULL, &sig_len, msg, msg_len) != 1) { 105 if(EVP_DigestSign(md_ctx, NULL, &sig_len, msg, msg_len) != 1) {
101 lua_pushnil(L); 106 lua_pushnil(L);
102 return 1; 107 return 1;
103 } 108 }
117 122
118 return 1; 123 return 1;
119 } 124 }
120 125
121 static int base_evp_verify(lua_State *L, const int key_type, const EVP_MD *digest_type) { 126 static int base_evp_verify(lua_State *L, const int key_type, const EVP_MD *digest_type) {
122 EVP_PKEY *pkey = pkey_from_arg(L, 1, key_type, 0); 127 EVP_PKEY *pkey = pkey_from_arg(L, 1, (key_type!=NID_rsassaPss)?key_type:NID_rsaEncryption, 0);
123 128
124 size_t msg_len; 129 size_t msg_len;
125 const unsigned char *msg = (unsigned char*)luaL_checklstring(L, 2, &msg_len); 130 const unsigned char *msg = (unsigned char*)luaL_checklstring(L, 2, &msg_len);
126 131
127 size_t sig_len; 132 size_t sig_len;
130 EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); 135 EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
131 136
132 if(EVP_DigestVerifyInit(md_ctx, NULL, digest_type, NULL, pkey) != 1) { 137 if(EVP_DigestVerifyInit(md_ctx, NULL, digest_type, NULL, pkey) != 1) {
133 lua_pushnil(L); 138 lua_pushnil(L);
134 goto cleanup; 139 goto cleanup;
140 }
141 if(key_type == NID_rsassaPss) {
142 EVP_PKEY_CTX_set_rsa_padding(EVP_MD_CTX_pkey_ctx(md_ctx), RSA_PKCS1_PSS_PADDING);
135 } 143 }
136 int result = EVP_DigestVerify(md_ctx, sig, sig_len, msg, msg_len); 144 int result = EVP_DigestVerify(md_ctx, sig, sig_len, msg, msg_len);
137 if(result == 0) { 145 if(result == 0) {
138 lua_pushboolean(L, 0); 146 lua_pushboolean(L, 0);
139 } else if(result != 1) { 147 } else if(result != 1) {
277 285
278 static int Led25519_verify(lua_State *L) { 286 static int Led25519_verify(lua_State *L) {
279 return base_evp_verify(L, NID_ED25519, NULL); 287 return base_evp_verify(L, NID_ED25519, NULL);
280 } 288 }
281 289
290 static int Lrsassa_pkcs1_256_sign(lua_State *L) {
291 return base_evp_sign(L, NID_rsaEncryption, EVP_sha256());
292 }
293
294 static int Lrsassa_pkcs1_256_verify(lua_State *L) {
295 return base_evp_verify(L, NID_rsaEncryption, EVP_sha256());
296 }
297
298 static int Lrsassa_pss_256_sign(lua_State *L) {
299 return base_evp_sign(L, NID_rsassaPss, EVP_sha256());
300 }
301
302 static int Lrsassa_pss_256_verify(lua_State *L) {
303 return base_evp_verify(L, NID_rsassaPss, EVP_sha256());
304 }
305
282 /* gcm_encrypt(key, iv, plaintext) */ 306 /* gcm_encrypt(key, iv, plaintext) */
283 static int Laes_gcm_encrypt(lua_State *L, const EVP_CIPHER *cipher, const unsigned char expected_key_len) { 307 static int Laes_gcm_encrypt(lua_State *L, const EVP_CIPHER *cipher, const unsigned char expected_key_len) {
284 EVP_CIPHER_CTX *ctx; 308 EVP_CIPHER_CTX *ctx;
285 luaL_Buffer ciphertext_buffer; 309 luaL_Buffer ciphertext_buffer;
286 310
501 } 525 }
502 526
503 static const luaL_Reg Reg[] = { 527 static const luaL_Reg Reg[] = {
504 { "ed25519_sign", Led25519_sign }, 528 { "ed25519_sign", Led25519_sign },
505 { "ed25519_verify", Led25519_verify }, 529 { "ed25519_verify", Led25519_verify },
530 { "rsassa_pkcs1_256_sign", Lrsassa_pkcs1_256_sign },
531 { "rsassa_pkcs1_256_verify", Lrsassa_pkcs1_256_verify },
532 { "rsassa_pss_256_sign", Lrsassa_pss_256_sign },
533 { "rsassa_pss_256_verify", Lrsassa_pss_256_verify },
506 { "aes_128_gcm_encrypt", Laes_128_gcm_encrypt }, 534 { "aes_128_gcm_encrypt", Laes_128_gcm_encrypt },
507 { "aes_128_gcm_decrypt", Laes_128_gcm_decrypt }, 535 { "aes_128_gcm_decrypt", Laes_128_gcm_decrypt },
508 { "aes_256_gcm_encrypt", Laes_256_gcm_encrypt }, 536 { "aes_256_gcm_encrypt", Laes_256_gcm_encrypt },
509 { "aes_256_gcm_decrypt", Laes_256_gcm_decrypt }, 537 { "aes_256_gcm_decrypt", Laes_256_gcm_decrypt },
510 { "ecdsa_sha256_sign", Lecdsa_sha256_sign }, 538 { "ecdsa_sha256_sign", Lecdsa_sha256_sign },