Software /
code /
prosody
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 }, |