mirror of https://github.com/nodejs/node.git
Merge branch 'v0.4'
Conflicts: doc/api/modules.markdown test/simple/test-crypto.jspull/5370/head
commit
3d7d994ffc
|
@ -139,11 +139,13 @@ This is the mirror of the signing object above.
|
|||
Updates the verifier object with data.
|
||||
This can be called many times with new data as it is streamed.
|
||||
|
||||
### verifier.verify(cert, signature, signature_format='binary')
|
||||
### verifier.verify(object, signature, signature_format='binary')
|
||||
|
||||
Verifies the signed data by using the `cert` which is a string containing
|
||||
the PEM encoded certificate, and `signature`, which is the previously calculated
|
||||
signature for the data, in the `signature_format` which can be `'binary'`, `'hex'` or `'base64'`.
|
||||
Verifies the signed data by using the `object` and `signature`. `object` is a
|
||||
string containing a PEM encoded object, which can be one of RSA public key,
|
||||
DSA public key, or X.509 certificate. `signature` is the previously calculated
|
||||
signature for the data, in the `signature_format` which can be `'binary'`,
|
||||
`'hex'` or `'base64'`.
|
||||
|
||||
Returns true or false depending on the validity of the signature for the data and public key.
|
||||
|
||||
|
|
|
@ -330,6 +330,7 @@ Because `module` provides a `filename` property (normally equivalent to
|
|||
`__filename`), the entry point of the current application can be obtained
|
||||
by checking `require.main.filename`.
|
||||
|
||||
|
||||
## AMD Compatibility
|
||||
|
||||
Node's modules have access to a function named `define`, which may be
|
||||
|
@ -362,6 +363,23 @@ The example module above could be structured like so:
|
|||
Node executes the callback immediately, so please plan your programs
|
||||
accordingly.
|
||||
|
||||
|
||||
### Accessing the main module
|
||||
|
||||
When a file is run directly from Node, `require.main` is set to its
|
||||
`module`. That means that you can determine whether a file has been run
|
||||
directly by testing
|
||||
|
||||
require.main === module
|
||||
|
||||
For a file `foo.js`, this will be `true` if run via `node foo.js`, but
|
||||
`false` if run by `require('./foo')`.
|
||||
|
||||
Because `module` provides a `filename` property (normally equivalent to
|
||||
`__filename`), the entry point of the current application can be obtained
|
||||
by checking `require.main.filename`.
|
||||
|
||||
|
||||
## Addenda: Package Manager Tips
|
||||
|
||||
The semantics of Node's `require()` function were designed to be general
|
||||
|
|
|
@ -423,6 +423,11 @@ exports.pump = function(readStream, writeStream, callback) {
|
|||
exports.inherits = function(ctor, superCtor) {
|
||||
ctor.super_ = superCtor;
|
||||
ctor.prototype = Object.create(superCtor.prototype, {
|
||||
constructor: { value: ctor, enumerable: false }
|
||||
constructor: {
|
||||
value: ctor,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -42,6 +42,11 @@
|
|||
return ThrowException(Exception::TypeError(String::New("Not a string or buffer"))); \
|
||||
}
|
||||
|
||||
static const char *RSA_PUB_KEY_PFX = "-----BEGIN RSA PUBLIC KEY-----";
|
||||
static const char *DSA_PUB_KEY_PFX = "-----BEGIN PUBLIC KEY-----";
|
||||
static const int RSA_PUB_KEY_PFX_LEN = strlen(RSA_PUB_KEY_PFX);
|
||||
static const int DSA_PUB_KEY_PFX_LEN = strlen(DSA_PUB_KEY_PFX);
|
||||
|
||||
namespace node {
|
||||
namespace crypto {
|
||||
|
||||
|
@ -1647,7 +1652,7 @@ class Cipher : public ObjectWrap {
|
|||
|
||||
static Handle<Value> CipherInitIv(const Arguments& args) {
|
||||
Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
|
||||
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
cipher->incomplete_base64=NULL;
|
||||
|
@ -1682,7 +1687,7 @@ class Cipher : public ObjectWrap {
|
|||
assert(iv_written == iv_len);
|
||||
|
||||
String::Utf8Value cipherType(args[0]->ToString());
|
||||
|
||||
|
||||
bool r = cipher->CipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
|
||||
|
||||
delete [] key_buf;
|
||||
|
@ -1976,7 +1981,7 @@ class Decipher : public ObjectWrap {
|
|||
|
||||
static Handle<Value> DecipherInit(const Arguments& args) {
|
||||
Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
|
||||
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
cipher->incomplete_utf8=NULL;
|
||||
|
@ -2000,7 +2005,7 @@ class Decipher : public ObjectWrap {
|
|||
assert(key_written == key_len);
|
||||
|
||||
String::Utf8Value cipherType(args[0]->ToString());
|
||||
|
||||
|
||||
bool r = cipher->DecipherInit(*cipherType, key_buf,key_len);
|
||||
|
||||
delete [] key_buf;
|
||||
|
@ -2014,7 +2019,7 @@ class Decipher : public ObjectWrap {
|
|||
|
||||
static Handle<Value> DecipherInitIv(const Arguments& args) {
|
||||
Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
|
||||
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
cipher->incomplete_utf8=NULL;
|
||||
|
@ -2050,7 +2055,7 @@ class Decipher : public ObjectWrap {
|
|||
assert(iv_written == iv_len);
|
||||
|
||||
String::Utf8Value cipherType(args[0]->ToString());
|
||||
|
||||
|
||||
bool r = cipher->DecipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
|
||||
|
||||
delete [] key_buf;
|
||||
|
@ -2415,7 +2420,7 @@ class Hmac : public ObjectWrap {
|
|||
}
|
||||
|
||||
int r;
|
||||
|
||||
|
||||
if( Buffer::HasInstance(args[0])) {
|
||||
Local<Object> buffer_obj = args[0]->ToObject();
|
||||
char *buffer_data = Buffer::Data(buffer_obj);
|
||||
|
@ -2906,29 +2911,58 @@ class Verify : public ObjectWrap {
|
|||
int VerifyFinal(char* key_pem, int key_pemLen, unsigned char* sig, int siglen) {
|
||||
if (!initialised_) return 0;
|
||||
|
||||
EVP_PKEY* pkey = NULL;
|
||||
BIO *bp = NULL;
|
||||
EVP_PKEY* pkey;
|
||||
X509 *x509;
|
||||
X509 *x509 = NULL;
|
||||
int r = 0;
|
||||
|
||||
bp = BIO_new(BIO_s_mem());
|
||||
if(!BIO_write(bp, key_pem, key_pemLen)) return 0;
|
||||
|
||||
x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL );
|
||||
if (x509==NULL) return 0;
|
||||
|
||||
pkey=X509_get_pubkey(x509);
|
||||
if (pkey==NULL) return 0;
|
||||
|
||||
int r = EVP_VerifyFinal(&mdctx, sig, siglen, pkey);
|
||||
EVP_PKEY_free (pkey);
|
||||
|
||||
if (r != 1) {
|
||||
ERR_print_errors_fp (stderr);
|
||||
if (bp == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
X509_free(x509);
|
||||
BIO_free(bp);
|
||||
if(!BIO_write(bp, key_pem, key_pemLen)) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if this is an RSA or DSA "raw" public key before trying
|
||||
// X.509
|
||||
if (strncmp(key_pem, RSA_PUB_KEY_PFX, RSA_PUB_KEY_PFX_LEN) == 0 ||
|
||||
strncmp(key_pem, DSA_PUB_KEY_PFX, DSA_PUB_KEY_PFX_LEN) == 0) {
|
||||
pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
|
||||
if (pkey == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// X.509 fallback
|
||||
x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
|
||||
if (x509 == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey = X509_get_pubkey(x509);
|
||||
if (pkey == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
r = EVP_VerifyFinal(&mdctx, sig, siglen, pkey);
|
||||
if (r != 1)
|
||||
ERR_print_errors_fp (stderr);
|
||||
|
||||
if(pkey != NULL)
|
||||
EVP_PKEY_free (pkey);
|
||||
if (x509 != NULL)
|
||||
X509_free(x509);
|
||||
if (bp != NULL)
|
||||
BIO_free(bp);
|
||||
EVP_MD_CTX_cleanup(&mdctx);
|
||||
initialised_ = false;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF
|
||||
NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F
|
||||
UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB
|
||||
AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA
|
||||
QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK
|
||||
kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg
|
||||
f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u
|
||||
412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc
|
||||
mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7
|
||||
kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA
|
||||
gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
|
||||
G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
|
||||
7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,6 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
|
||||
6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
|
||||
Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
|
||||
oYi+1hqp1fIekaxsyQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
|
@ -36,6 +36,8 @@ var path = require('path');
|
|||
var caPem = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii');
|
||||
var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii');
|
||||
var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii');
|
||||
var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem', 'ascii');
|
||||
var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem', 'ascii');
|
||||
|
||||
try {
|
||||
var credentials = crypto.createCredentials(
|
||||
|
@ -145,6 +147,7 @@ assert.throws(function() {
|
|||
crypto.createHash('sha1').update({foo: 'bar'});
|
||||
}, /string or buffer/);
|
||||
|
||||
|
||||
// Test Diffie-Hellman with two parties sharing a secret,
|
||||
// using various encodings as we go along
|
||||
var dh1 = crypto.createDiffieHellman(256);
|
||||
|
@ -172,3 +175,17 @@ assert.equal(dh1.getPrivateKey(), dh3.getPrivateKey());
|
|||
var secret3 = dh3.computeSecret(key2, 'hex', 'base64');
|
||||
|
||||
assert.equal(secret1, secret3);
|
||||
|
||||
|
||||
// Test RSA key signing/verification
|
||||
var rsaSign = crypto.createSign('RSA-SHA1');
|
||||
var rsaVerify = crypto.createVerify('RSA-SHA1');
|
||||
assert.ok(rsaSign);
|
||||
assert.ok(rsaVerify);
|
||||
|
||||
rsaSign.update(rsaPubPem);
|
||||
var rsaSignature = rsaSign.sign(rsaKeyPem, 'hex');
|
||||
assert.equal(rsaSignature, '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6');
|
||||
|
||||
rsaVerify.update(rsaPubPem);
|
||||
assert.equal(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), 1);
|
||||
|
|
Loading…
Reference in New Issue