Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
node_crypto: use EVP_Cipher*_ex methods, not 'obsolete' versions
This also fixes an issue that made blowfish's ECB mode unusable.
  • Loading branch information
KiNgMaR authored and bnoordhuis committed Nov 30, 2011
1 parent 5fea005 commit 2603832
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 21 deletions.
53 changes: 32 additions & 21 deletions src/node_crypto.cc
Expand Up @@ -1900,15 +1900,19 @@ class Cipher : public ObjectWrap {
}

unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
int key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL, (unsigned char*) key_buf, key_buf_len, 1, key, iv);
int key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL,
(unsigned char*) key_buf, key_buf_len, 1, key, iv);

EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit(&ctx,cipher,(unsigned char *)key,(unsigned char *)iv, true);
if (!EVP_CIPHER_CTX_set_key_length(&ctx,key_len)) {
EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, NULL, true);
if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
EVP_CIPHER_CTX_cleanup(&ctx);
return false;
}
EVP_CipherInit_ex(&ctx, NULL, NULL,
(unsigned char *)key,
(unsigned char *)iv, true);
initialised_ = true;
return true;
}
Expand All @@ -1924,17 +1928,23 @@ class Cipher : public ObjectWrap {
fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
return false;
}
if (EVP_CIPHER_iv_length(cipher)!=iv_len) {
/* OpenSSL versions up to 0.9.8l failed to return the correct
iv_length (0) for ECB ciphers */
if (EVP_CIPHER_iv_length(cipher) != iv_len &&
!(EVP_CIPHER_mode(cipher) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
fprintf(stderr, "node-crypto : Invalid IV length %d\n", iv_len);
return false;
}
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit(&ctx,cipher,(unsigned char *)key,(unsigned char *)iv, true);
if (!EVP_CIPHER_CTX_set_key_length(&ctx,key_len)) {
EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, NULL, true);
if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
EVP_CIPHER_CTX_cleanup(&ctx);
return false;
}
EVP_CipherInit_ex(&ctx, NULL, NULL,
(unsigned char *)key,
(unsigned char *)iv, true);
initialised_ = true;
return true;
}
Expand All @@ -1952,7 +1962,7 @@ class Cipher : public ObjectWrap {
int CipherFinal(unsigned char** out, int *out_len) {
if (!initialised_) return 0;
*out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx)];
EVP_CipherFinal(&ctx,*out,out_len);
EVP_CipherFinal_ex(&ctx,*out,out_len);
EVP_CIPHER_CTX_cleanup(&ctx);
initialised_ = false;
return 1;
Expand Down Expand Up @@ -2271,16 +2281,15 @@ class Decipher : public ObjectWrap {
iv);

EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit(&ctx,
cipher_,
(unsigned char*)(key),
(unsigned char *)(iv),
false);
if (!EVP_CIPHER_CTX_set_key_length(&ctx,key_len)) {
EVP_CipherInit_ex(&ctx, cipher_, NULL, NULL, NULL, false);
if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
EVP_CIPHER_CTX_cleanup(&ctx);
return false;
}
EVP_CipherInit_ex(&ctx, NULL, NULL,
(unsigned char *)key,
(unsigned char *)iv, false);
initialised_ = true;
return true;
}
Expand All @@ -2296,21 +2305,23 @@ class Decipher : public ObjectWrap {
fprintf(stderr, "node-crypto : Unknown cipher %s\n", cipherType);
return false;
}
if (EVP_CIPHER_iv_length(cipher_) != iv_len) {
/* OpenSSL versions up to 0.9.8l failed to return the correct
iv_length (0) for ECB ciphers */
if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
!(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
fprintf(stderr, "node-crypto : Invalid IV length %d\n", iv_len);
return false;
}
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit(&ctx,
cipher_,
(unsigned char*)(key),
(unsigned char *)(iv),
false);
if (!EVP_CIPHER_CTX_set_key_length(&ctx,key_len)) {
EVP_CipherInit_ex(&ctx, cipher_, NULL, NULL, NULL, false);
if (!EVP_CIPHER_CTX_set_key_length(&ctx, key_len)) {
fprintf(stderr, "node-crypto : Invalid key length %d\n", key_len);
EVP_CIPHER_CTX_cleanup(&ctx);
return false;
}
EVP_CipherInit_ex(&ctx, NULL, NULL,
(unsigned char *)key,
(unsigned char *)iv, false);
initialised_ = true;
return true;
}
Expand All @@ -2331,7 +2342,7 @@ class Decipher : public ObjectWrap {
if (tolerate_padding) {
local_EVP_DecryptFinal_ex(&ctx,*out,out_len);
} else {
EVP_CipherFinal(&ctx,*out,out_len);
EVP_CipherFinal_ex(&ctx,*out,out_len);
}
EVP_CIPHER_CTX_cleanup(&ctx);
initialised_ = false;
Expand Down
52 changes: 52 additions & 0 deletions test/simple/test-crypto-ecb.js
@@ -0,0 +1,52 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.




var common = require('../common');
var assert = require('assert');

try {
var crypto = require('crypto');
} catch (e) {
console.log('Not compiled with OPENSSL support.');
process.exit();
}

// Testing whether EVP_CipherInit_ex is functioning correctly.
// Reference: bug#1997

(function()
{
var encrypt = crypto.createCipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', '');
var hex = encrypt.update('Hello World!', 'ascii', 'hex');
hex += encrypt.final('hex');
assert.equal(hex.toUpperCase(), '6D385F424AAB0CFBF0BB86E07FFB7D71');
}());

(function()
{
var decrypt = crypto.createDecipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', '');
var msg = decrypt.update('6D385F424AAB0CFBF0BB86E07FFB7D71', 'hex', 'ascii');
msg += decrypt.final('ascii');
assert.equal(msg, 'Hello World!');
}());

0 comments on commit 2603832

Please sign in to comment.