Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
T
tarantool
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
core
tarantool
Commits
e9db303e
Commit
e9db303e
authored
9 years ago
by
Georgy Kirichenko
Browse files
Options
Downloads
Patches
Plain Diff
Properly handle openssl errors. Fixed #1383
parent
f9601599
Loading
Loading
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
src/lua/crypto.lua
+43
-13
43 additions, 13 deletions
src/lua/crypto.lua
test/app/crypto.result
+110
-0
110 additions, 0 deletions
test/app/crypto.result
test/app/crypto.test.lua
+38
-0
38 additions, 0 deletions
test/app/crypto.test.lua
test/app/digest.result
+2
-1
2 additions, 1 deletion
test/app/digest.result
with
193 additions
and
14 deletions
src/lua/crypto.lua
+
43
−
13
View file @
e9db303e
...
...
@@ -4,6 +4,12 @@ local ffi = require 'ffi'
local
buffer
=
require
(
'buffer'
)
ffi
.
cdef
[[
/* from openssl/err.h */
unsigned long ERR_get_error(void);
char *ERR_error_string(unsigned long e, char *buf);
void ERR_load_ERR_strings(void);
void ERR_load_crypto_strings(void);
/* from openssl/evp.h */
void OpenSSL_add_all_digests();
void OpenSSL_add_all_ciphers();
...
...
@@ -50,11 +56,16 @@ if ssl == nil then
if
ssl
~=
nil
then
ssl
.
OpenSSL_add_all_digests
()
ssl
.
OpenSSL_add_all_ciphers
()
ssl
.
ERR_load_crypto_strings
()
break
end
end
end
local
function
openssl_err_str
()
return
ffi
.
string
(
ssl
.
ERR_error_string
(
ssl
.
ERR_get_error
(),
nil
))
end
local
digests
=
{}
if
ssl
then
for
class
,
name
in
pairs
({
...
...
@@ -62,7 +73,10 @@ if ssl then
sha
=
'SHA'
,
sha1
=
'SHA1'
,
sha224
=
'SHA224'
,
sha256
=
'SHA256'
,
sha384
=
'SHA384'
,
sha512
=
'SHA512'
,
dss
=
'DSS'
,
dss1
=
'DSS1'
,
mdc2
=
'MDC2'
,
ripemd160
=
'RIPEMD160'
})
do
digests
[
class
]
=
ssl
.
EVP_get_digestbyname
(
class
)
local
digest
=
ssl
.
EVP_get_digestbyname
(
class
)
if
digest
~=
nil
then
digests
[
class
]
=
digest
end
end
end
...
...
@@ -75,7 +89,7 @@ end
local
function
digest_new
(
digest
)
local
ctx
=
ssl
.
EVP_MD_CTX_create
()
if
ctx
==
nil
then
return
error
(
'Can\'
t
create
digest
ctx
'
)
return
error
(
'Can\'
t
create
digest
ctx
:
' .. openssl_err_str()
)
end
ffi.gc(ctx, digest_gc)
local self = setmetatable({
...
...
@@ -94,7 +108,7 @@ local function digest_init(self)
return error('
Digest
context
isn
\
't usable'
)
end
if
ssl
.
EVP_DigestInit_ex
(
self
.
ctx
,
self
.
digest
,
nil
)
~=
1
then
return
error
(
'Can\'
t
init
digest
'
)
return
error
(
'Can\'
t
init
digest
:
' .. openssl_err_str()
)
end
self.initialized = true
end
...
...
@@ -104,7 +118,7 @@ local function digest_update(self, input)
return error('
Digest
not
initialized
')
end
if ssl.EVP_DigestUpdate(self.ctx, input, input:len()) ~= 1 then
return error('
Can
\
't update digest
'
)
return error('
Can
\
't update digest
: '
..
openssl_err_str
()
)
end
end
...
...
@@ -114,7 +128,7 @@ local function digest_final(self)
end
self
.
initialized
=
false
if
ssl
.
EVP_DigestFinal_ex
(
self
.
ctx
,
self
.
buf
.
wpos
,
self
.
outl
)
~=
1
then
return
error
(
'Can\'
t
finalize
digest
'
)
return
error
(
'Can\'
t
finalize
digest
:
' .. openssl_err_str()
)
end
return ffi.string(self.buf.wpos, self.outl[0])
end
...
...
@@ -142,8 +156,11 @@ if ssl then
local algo_api = {}
for mode, mode_name in pairs({cfb = '
CFB
', ofb = '
OFB
',
cbc = '
CBC
', ecb = '
ECB
'}) do
algo_api[mode]
=
local cipher
=
ssl.EVP_get_cipherbyname(algo_name .. '
-
' .. mode_name)
if cipher ~= nil then
algo_api[mode] = cipher
end
end
if algo_api ~= {} then
ciphers[algo] = algo_api
...
...
@@ -158,15 +175,24 @@ local function cipher_gc(ctx)
end
local function cipher_new(cipher, key, iv, direction)
local block_size = ssl.EVP_CIPHER_block_size(cipher)
if key == nil or key:len() < block_size then
return error('
Key
length
should
be
equal
cipher
block
size
(
'
.. tostring(block_size) .. '
)
')
end
if iv == nil or iv:len() < block_size then
return error('
Initial
vector
length
should
be
equal
cipher
block
size
(
'
.. tostring(block_size) .. '
)
')
end
local ctx = ssl.EVP_CIPHER_CTX_new()
if ctx == nil then
return error('
Can
\
't create cipher ctx
'
)
return error('
Can
\
't create cipher ctx
: '
..
openssl_err_str
()
)
end
ffi
.
gc
(
ctx
,
cipher_gc
)
local
self
=
setmetatable
({
ctx
=
ctx
,
cipher
=
cipher
,
block_size
=
ssl
.
EVP_CIPHER_
block_size
(
cipher
)
,
block_size
=
block_size
,
direction
=
direction
,
buf
=
buffer
.
ibuf
(),
initialized
=
false
,
...
...
@@ -180,9 +206,9 @@ local function cipher_init(self, key, iv)
if
self
.
ctx
==
nil
then
return
error
(
'Cipher context isn\'
t
usable
')
end
if ssl.EVP_CipherInit_ex(self.ctx, self.cipher, nil,
if ssl.EVP_CipherInit_ex(self.ctx, self.cipher, nil,
key, iv, self.direction) ~= 1 then
return error('
Can
\
't init cipher
'
)
return error('
Can
\
't init cipher
:'
..
openssl_err_str
()
)
end
self
.
initialized
=
true
end
...
...
@@ -191,9 +217,13 @@ local function cipher_update(self, input)
if
not
self
.
initialized
then
return
error
(
'Cipher not initialized'
)
end
if
input
==
nil
then
return
''
end
input
=
tostring
(
input
)
local
wpos
=
self
.
buf
:
reserve
(
input
:
len
()
+
self
.
block_size
-
1
)
if
ssl
.
EVP_CipherUpdate
(
self
.
ctx
,
wpos
,
self
.
outl
,
input
,
input
:
len
())
~=
1
then
return
error
(
'Can\'
t
update
cipher
'
)
return
error
(
'Can\'
t
update
cipher
:
' .. openssl_err_str()
)
end
return ffi.string(wpos, self.outl[0])
end
...
...
@@ -205,7 +235,7 @@ local function cipher_final(self)
self.initialized = false
local wpos = self.buf:reserve(self.block_size - 1)
if ssl.EVP_CipherFinal_ex(self.ctx, wpos, self.outl) ~= 1 then
return error('
Can
\
't finalize cipher
'
)
return error('
Can
\
't finalize cipher
:'
..
openssl_err_str
()
)
end
self
.
initialized
=
false
return
ffi
.
string
(
wpos
,
self
.
outl
[
0
])
...
...
@@ -254,7 +284,7 @@ digest_api = setmetatable(digest_api,
' is not supported or SSL library not found'
)
end
})
local
function
cipher_mode_error
(
self
,
mode
)
error
(
'Cipher mode'
..
mode
..
' is not supported'
)
error
(
'Cipher mode
'
..
mode
..
' is not supported'
)
end
local
cipher_api
=
{}
...
...
This diff is collapsed.
Click to expand it.
test/app/crypto.result
0 → 100644
+
110
−
0
View file @
e9db303e
crypto = require('crypto')
---
...
type(crypto)
---
- table
...
ciph = crypto.cipher.aes128.cbc
---
...
pass = '12345678876543211234567887654321'
---
...
iv = 'abcdefghijklmnopqrstuvwxyz123456'
---
...
enc = ciph.encrypt('test', pass, iv)
---
...
enc
---
- !!binary WpJJu6l6oziZcyvND8KueA==
...
ciph.decrypt(enc, pass, iv)
---
- test
...
--Failing scenaries
crypto.cipher.aes128.cbc.encrypt('a')
---
- error: 'builtin/crypto.lua:302: Key length should be equal cipher block size (16)'
...
crypto.cipher.aes128.cbc.encrypt('a', '123456', '435')
---
- error: 'builtin/crypto.lua:302: Key length should be equal cipher block size (16)'
...
crypto.cipher.aes128.cbc.encrypt('a', '1234567887654321')
---
- error: 'builtin/crypto.lua:302: Initial vector length should be equal cipher block
size (16)'
...
crypto.cipher.aes128.cbc.encrypt('a', '1234567887654321', '12')
---
- error: 'builtin/crypto.lua:302: Initial vector length should be equal cipher block
size (16)'
...
crypto.cipher.aes256.cbc.decrypt('a')
---
- error: 'builtin/crypto.lua:302: Key length should be equal cipher block size (16)'
...
crypto.cipher.aes256.cbc.decrypt('a', '123456', '435')
---
- error: 'builtin/crypto.lua:302: Key length should be equal cipher block size (16)'
...
crypto.cipher.aes256.cbc.decrypt('a', '12345678876543211234567887654321')
---
- error: 'builtin/crypto.lua:302: Initial vector length should be equal cipher block
size (16)'
...
crypto.cipher.aes256.cbc.decrypt('12', '12345678876543211234567887654321', '12')
---
- error: 'builtin/crypto.lua:302: Initial vector length should be equal cipher block
size (16)'
...
crypto.cipher.aes192.cbc.encrypt.new()
---
- error: Key length should be equal cipher block size (16)
...
crypto.cipher.aes192.cbc.encrypt.new('123321')
---
- error: Key length should be equal cipher block size (16)
...
crypto.cipher.aes192.cbc.decrypt.new('123456788765432112345678')
---
- error: Initial vector length should be equal cipher block size (16)
...
crypto.cipher.aes192.cbc.decrypt.new('123456788765432112345678', '12345')
---
- error: Initial vector length should be equal cipher block size (16)
...
crypto.cipher.aes100.efb
---
- error: 'builtin/crypto.lua:318: Cipher method aes100 is not supported or SSL library
not found'
...
crypto.cipher.aes256.nomode
---
- error: 'builtin/crypto.lua:287: Cipher mode nomode is not supported'
...
crypto.digest.nodigest
---
- error: 'builtin/crypto.lua:283: Digest method nodigest is not supported or SSL library
not found'
...
bad_pass = '87654321123456788765432112345678'
---
...
bad_iv = '123456abcdefghijklmnopqrstuvwxyz'
---
...
ciph.decrypt(enc, bad_pass, iv)
---
- error: 'builtin/crypto.lua:304: Can''t finalize cipher:error:06065064:digital envelope
routines:EVP_DecryptFinal_ex:bad decrypt'
...
ciph.decrypt(enc, pass, bad_iv)
---
- error: 'builtin/crypto.lua:304: Can''t finalize cipher:error:06065064:digital envelope
routines:EVP_DecryptFinal_ex:bad decrypt'
...
This diff is collapsed.
Click to expand it.
test/app/crypto.test.lua
0 → 100644
+
38
−
0
View file @
e9db303e
crypto
=
require
(
'crypto'
)
type
(
crypto
)
ciph
=
crypto
.
cipher
.
aes128
.
cbc
pass
=
'12345678876543211234567887654321'
iv
=
'abcdefghijklmnopqrstuvwxyz123456'
enc
=
ciph
.
encrypt
(
'test'
,
pass
,
iv
)
enc
ciph
.
decrypt
(
enc
,
pass
,
iv
)
--Failing scenaries
crypto
.
cipher
.
aes128
.
cbc
.
encrypt
(
'a'
)
crypto
.
cipher
.
aes128
.
cbc
.
encrypt
(
'a'
,
'123456'
,
'435'
)
crypto
.
cipher
.
aes128
.
cbc
.
encrypt
(
'a'
,
'1234567887654321'
)
crypto
.
cipher
.
aes128
.
cbc
.
encrypt
(
'a'
,
'1234567887654321'
,
'12'
)
crypto
.
cipher
.
aes256
.
cbc
.
decrypt
(
'a'
)
crypto
.
cipher
.
aes256
.
cbc
.
decrypt
(
'a'
,
'123456'
,
'435'
)
crypto
.
cipher
.
aes256
.
cbc
.
decrypt
(
'a'
,
'12345678876543211234567887654321'
)
crypto
.
cipher
.
aes256
.
cbc
.
decrypt
(
'12'
,
'12345678876543211234567887654321'
,
'12'
)
crypto
.
cipher
.
aes192
.
cbc
.
encrypt
.
new
()
crypto
.
cipher
.
aes192
.
cbc
.
encrypt
.
new
(
'123321'
)
crypto
.
cipher
.
aes192
.
cbc
.
decrypt
.
new
(
'123456788765432112345678'
)
crypto
.
cipher
.
aes192
.
cbc
.
decrypt
.
new
(
'123456788765432112345678'
,
'12345'
)
crypto
.
cipher
.
aes100
.
efb
crypto
.
cipher
.
aes256
.
nomode
crypto
.
digest
.
nodigest
bad_pass
=
'87654321123456788765432112345678'
bad_iv
=
'123456abcdefghijklmnopqrstuvwxyz'
ciph
.
decrypt
(
enc
,
bad_pass
,
iv
)
ciph
.
decrypt
(
enc
,
pass
,
bad_iv
)
This diff is collapsed.
Click to expand it.
test/app/digest.result
+
2
−
1
View file @
e9db303e
...
...
@@ -326,7 +326,8 @@ digest.aes256cbc.decrypt(digest.aes256cbc.encrypt('test123', 'passpasspasspasspa
...
digest.aes256cbc.decrypt(digest.aes256cbc.encrypt('test123', 'passpasspasspasspasspasspasspass', 'iv12tras8712cvbhuytrghjklmnbdr34'), 'nosspasspasspasspasspasspasspass', 'iv12tras8712cvbhuytrghjklmnbdr34')
---
- error: 'builtin/crypto.lua:274: Can''t finalize cipher'
- error: 'builtin/crypto.lua:304: Can''t finalize cipher:error:06065064:digital envelope
routines:EVP_DecryptFinal_ex:bad decrypt'
...
digest = nil
---
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment