Browse Source

crypto: improve cipher/decipher error messages

Throw the OpenSSL error string instead of the rather less informative
error message "fail".
v0.9.10-release
Ben Noordhuis 12 years ago
parent
commit
f5f9e8da71
  1. 59
      src/node_crypto.cc
  2. 5
      test/simple/test-crypto.js

59
src/node_crypto.cc

@ -119,6 +119,22 @@ static void crypto_lock_cb(int mode, int n, const char* file, int line) {
} }
Handle<Value> ThrowCryptoErrorHelper(unsigned long err, bool is_type_error) {
HandleScope scope;
char errmsg[128];
ERR_error_string_n(err, errmsg, sizeof(errmsg));
return is_type_error ? ThrowTypeError(errmsg) : ThrowError(errmsg);
}
Handle<Value> ThrowCryptoError(unsigned long err) {
return ThrowCryptoErrorHelper(err, false);
}
Handle<Value> ThrowCryptoTypeError(unsigned long err) {
return ThrowCryptoErrorHelper(err, true);
}
void SecureContext::Initialize(Handle<Object> target) { void SecureContext::Initialize(Handle<Object> target) {
@ -347,9 +363,7 @@ Handle<Value> SecureContext::SetKey(const Arguments& args) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("PEM_read_bio_PrivateKey"))); String::New("PEM_read_bio_PrivateKey")));
} }
char string[120]; return ThrowCryptoError(err);
ERR_error_string_n(err, string, sizeof string);
return ThrowException(Exception::Error(String::New(string)));
} }
SSL_CTX_use_PrivateKey(sc->ctx_, key); SSL_CTX_use_PrivateKey(sc->ctx_, key);
@ -449,9 +463,7 @@ Handle<Value> SecureContext::SetCert(const Arguments& args) {
return ThrowException(Exception::Error( return ThrowException(Exception::Error(
String::New("SSL_CTX_use_certificate_chain"))); String::New("SSL_CTX_use_certificate_chain")));
} }
char string[120]; return ThrowCryptoError(err);
ERR_error_string_n(err, string, sizeof string);
return ThrowException(Exception::Error(String::New(string)));
} }
return True(node_isolate); return True(node_isolate);
@ -2095,9 +2107,7 @@ class Cipher : public ObjectWrap {
if (!initialised_) return 0; if (!initialised_) return 0;
*out_len=len+EVP_CIPHER_CTX_block_size(&ctx); *out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
*out= new unsigned char[*out_len]; *out= new unsigned char[*out_len];
return EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
return 1;
} }
int SetAutoPadding(bool auto_padding) { int SetAutoPadding(bool auto_padding) {
@ -2156,9 +2166,7 @@ class Cipher : public ObjectWrap {
delete [] key_buf; delete [] key_buf;
if (!r) { if (!r) return ThrowCryptoError(ERR_get_error());
return ThrowException(Exception::Error(String::New("CipherInit error")));
}
return args.This(); return args.This();
} }
@ -2210,9 +2218,7 @@ class Cipher : public ObjectWrap {
delete [] key_buf; delete [] key_buf;
delete [] iv_buf; delete [] iv_buf;
if (!r) { if (!r) return ThrowCryptoError(ERR_get_error());
return ThrowException(Exception::Error(String::New("CipherInitIv error")));
}
return args.This(); return args.This();
} }
@ -2231,10 +2237,9 @@ class Cipher : public ObjectWrap {
r = cipher->CipherUpdate(buffer_data, buffer_length, &out, &out_len); r = cipher->CipherUpdate(buffer_data, buffer_length, &out, &out_len);
if (!r) { if (r == 0) {
delete [] out; delete [] out;
Local<Value> exception = Exception::TypeError(String::New("DecipherUpdate fail")); return ThrowCryptoTypeError(ERR_get_error());
return ThrowException(exception);
} }
Local<Value> outString; Local<Value> outString;
@ -2272,11 +2277,7 @@ class Cipher : public ObjectWrap {
// out_value always get allocated. // out_value always get allocated.
delete[] out_value; delete[] out_value;
out_value = NULL; out_value = NULL;
if (r == 0) { if (r == 0) return ThrowCryptoTypeError(ERR_get_error());
Local<Value> exception = Exception::TypeError(
String::New("CipherFinal fail"));
return ThrowException(exception);
}
} }
outString = Encode(out_value, out_len, BUFFER); outString = Encode(out_value, out_len, BUFFER);
@ -2400,8 +2401,7 @@ class Decipher : public ObjectWrap {
*out_len=len+EVP_CIPHER_CTX_block_size(&ctx); *out_len=len+EVP_CIPHER_CTX_block_size(&ctx);
*out= new unsigned char[*out_len]; *out= new unsigned char[*out_len];
EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len); return EVP_CipherUpdate(&ctx, *out, out_len, (unsigned char*)data, len);
return 1;
} }
int SetAutoPadding(bool auto_padding) { int SetAutoPadding(bool auto_padding) {
@ -2551,8 +2551,7 @@ class Decipher : public ObjectWrap {
if (!r) { if (!r) {
delete [] out; delete [] out;
Local<Value> exception = Exception::TypeError(String::New("DecipherUpdate fail")); return ThrowCryptoTypeError(ERR_get_error());
return ThrowException(exception);
} }
Local<Value> outString; Local<Value> outString;
@ -2591,11 +2590,7 @@ class Decipher : public ObjectWrap {
if (out_len == 0 || r == 0) { if (out_len == 0 || r == 0) {
delete [] out_value; // allocated even if out_len == 0 delete [] out_value; // allocated even if out_len == 0
out_value = NULL; out_value = NULL;
if (r == 0) { if (r == 0) return ThrowCryptoTypeError(ERR_get_error());
Local<Value> exception = Exception::TypeError(
String::New("DecipherFinal fail"));
return ThrowException(exception);
}
} }
outString = Encode(out_value, out_len, BUFFER); outString = Encode(out_value, out_len, BUFFER);

5
test/simple/test-crypto.js

@ -797,3 +797,8 @@ assert.notEqual(-1, crypto.getHashes().indexOf('sha'));
assert.equal(-1, crypto.getHashes().indexOf('SHA1')); assert.equal(-1, crypto.getHashes().indexOf('SHA1'));
assert.equal(-1, crypto.getHashes().indexOf('SHA')); assert.equal(-1, crypto.getHashes().indexOf('SHA'));
assertSorted(crypto.getHashes()); assertSorted(crypto.getHashes());
(function() {
var c = crypto.createDecipher('aes-128-ecb', '');
assert.throws(function() { c.final('utf8') }, /invalid public key/);
})();

Loading…
Cancel
Save