Browse Source

Rough convert of module to VerusHash

master
miketout 6 years ago
parent
commit
513149a7a9
  1. 4
      LICENSE
  2. 29
      README
  3. 1622
      crypto.cc
  4. 6
      package.json
  5. 56
      test.js
  6. 20
      test_cert.pem
  7. 15
      test_key.pem
  8. 178
      verushash.cc
  9. 23
      wscript

4
LICENSE

@ -1,4 +1,6 @@
// Copyright 2009, Acknack Ltd. All rights reserved.
// Copyright 2018 Michael Toutonghi. All rights reserved.
// portions Copyright 2009, Acknack Ltd. All rights reserved.
// 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

29
README

@ -1,26 +1,3 @@
node-crypto
===========
A wrapper around openssl for node.js, currently exposing Hashing, Signing
and Verifying methods.
Version 0.0.5 : test.js now uses mjsunit
Version 0.0.4 : Added package.json and updated tests to latest node version.
Version 0.0.3 : Added cipher / decipher, thanks to Frans-Willem Hardijzer.
To install, ensure that you have openssl installed, and run:
node-waf configure
node-waf build
This will put the crypto.node binary module in build/default.
The hashing, signing and verifying methods can work with binary, hex or
base64 encoded strings.
The encrypt / decrypt methods work with binary, hex or base64 encodings,
with streaming.
See test.js for example usage.
verushash-node
-----------------------
Implementation of the VerushHash hash algorithm as a node.js module

1622
crypto.cc

File diff suppressed because it is too large

6
package.json

@ -1,11 +1,11 @@
{ "name" : "crypto"
, "author" : "Rhys <rhys@wave.to>"
{ "name" : "verushash"
, "author" : "miketout"
, "version" : "0.0.5"
, "scripts" :
{ "preinstall" : "node-waf configure"
, "install" : "node-waf build"
, "test" : "node test.js"
}
, "main" : "build/default/crypto"
, "main" : "build/default/verushash"
, "engines" : [ "node" ]
}

56
test.js

@ -1,60 +1,16 @@
var crypto=require("./crypto");
var crypto=require("./verushash.cc");
var sys=require("sys");
var fs=require("fs");
var test=require("mjsunit");
// Test HMAC
var h1 = (new crypto.Hmac).init("sha1", "Node").update("some data").update("to hmac").digest("hex");
test.assertEquals(h1, '19fd6e1ba73d9ed2224dd5094a71babe85d9a892', "test HMAC");
// Test hashing
var a0 = (new crypto.Hash).init("sha1").update("Test123").digest("hex");
var a1 = (new crypto.Hash).init("md5").update("Test123").digest("binary");
var a2= (new crypto.Hash).init("sha256").update("Test123").digest("base64");
var a3 = (new crypto.Hash).init("sha512").update("Test123").digest(); // binary
var a0 = (new verushash.Hash).init("verus").update("Test123").digest("hex");
var a1 = (new verushash.Hash).init("verus").update("Test123").digest("binary");
var a3 = (new verushash.Hash).init("verus").update("Test123").digest(); // binary
// Test multiple updates to same hash
var h1 = (new crypto.Hash).init("sha1").update("Test123").digest("hex");
var h2 = (new crypto.Hash).init("sha1").update("Test").update("123").digest("hex");
var h1 = (new verushash.Hash).init("verus").update("Test123").digest("hex");
var h2 = (new verushash.Hash).init("verus").update("Test").update("123").digest("hex");
test.assertEquals(h1, h2, "multipled updates");
// Load our public and private keys
var keyPem = fs.readFileSync("test_key.pem");
var certPem = fs.readFileSync("test_cert.pem");
// Test signing and verifying
var s1 = (new crypto.Sign).init("RSA-SHA1").update("Test123").sign(keyPem, "base64");
var verified = !!((new crypto.Verify).init("RSA-SHA1").update("Test").update("123").verify(certPem, s1, "base64"));
test.assertTrue(verified, "sign and verify (base 64)");
var s2 = (new crypto.Sign).init("RSA-SHA256").update("Test123").sign(keyPem); // binary
var verified = !!((new crypto.Verify).init("RSA-SHA256").update("Test").update("123").verify(certPem, s2)); // binary
test.assertTrue(verified, "sign and verify (binary)");
// Test encryption and decryption
var plaintext="Keep this a secret? No! Tell everyone about node.js!";
var cipher=(new crypto.Cipher).init("aes192", "MySecretKey123");
var ciph=cipher.update(plaintext, 'utf8', 'hex'); // encrypt plaintext which is in utf8 format to a ciphertext which will be in hex
ciph+=cipher.final('hex'); // Only use binary or hex, not base64.
var decipher=(new crypto.Decipher).init("aes192", "MySecretKey123");
var txt = decipher.update(ciph, 'hex', 'utf8');
txt += decipher.final('utf8');
test.assertEquals(txt, plaintext, "encryption and decryption");
// Test encyrption and decryption with explicit key and iv
var encryption_key='0123456789abcd0123456789';
var iv = '12345678';
var cipher=(new crypto.Cipher).initiv("des-ede3-cbc", encryption_key, iv);
var ciph=cipher.update(plaintext, 'utf8', 'hex');
ciph+=cipher.final('hex');
var decipher=(new crypto.Decipher).initiv("des-ede3-cbc",encryption_key,iv);
var txt = decipher.update(ciph, 'hex', 'utf8');
txt += decipher.final('utf8');
test.assertEquals(txt, plaintext, "encryption and decryption with key and iv");

20
test_cert.pem

@ -1,20 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDXDCCAsWgAwIBAgIJAKL0UG+mRkSPMA0GCSqGSIb3DQEBBQUAMH0xCzAJBgNV
BAYTAlVLMRQwEgYDVQQIEwtBY2tuYWNrIEx0ZDETMBEGA1UEBxMKUmh5cyBKb25l
czEQMA4GA1UEChMHbm9kZS5qczEdMBsGA1UECxMUVGVzdCBUTFMgQ2VydGlmaWNh
dGUxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0wOTExMTEwOTUyMjJaFw0yOTExMDYw
OTUyMjJaMH0xCzAJBgNVBAYTAlVLMRQwEgYDVQQIEwtBY2tuYWNrIEx0ZDETMBEG
A1UEBxMKUmh5cyBKb25lczEQMA4GA1UEChMHbm9kZS5qczEdMBsGA1UECxMUVGVz
dCBUTFMgQ2VydGlmaWNhdGUxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG
9w0BAQEFAAOBjQAwgYkCgYEA8d8Hc6atq78Jt1HLp9agA/wpQfsFvkYUdZ1YsdvO
kL2janjwHQgMMCy/Njal3FUEW0OLPebKZUJ8L44JBXSlVxU4zyiiSOWld8EkTetR
AVT3WKQq3ud+cnxv7g8rGRQp1UHZwmdbZ1wEfAYq8QjYx6m1ciMgRo7DaDQhD29k
d+UCAwEAAaOB4zCB4DAdBgNVHQ4EFgQUL9miTJn+HKNuTmx/oMWlZP9cd4QwgbAG
A1UdIwSBqDCBpYAUL9miTJn+HKNuTmx/oMWlZP9cd4ShgYGkfzB9MQswCQYDVQQG
EwJVSzEUMBIGA1UECBMLQWNrbmFjayBMdGQxEzARBgNVBAcTClJoeXMgSm9uZXMx
EDAOBgNVBAoTB25vZGUuanMxHTAbBgNVBAsTFFRlc3QgVExTIENlcnRpZmljYXRl
MRIwEAYDVQQDEwlsb2NhbGhvc3SCCQCi9FBvpkZEjzAMBgNVHRMEBTADAQH/MA0G
CSqGSIb3DQEBBQUAA4GBADRXXA2xSUK5W1i3oLYWW6NEDVWkTQ9RveplyeS9MOkP
e7yPcpz0+O0ZDDrxR9chAiZ7fmdBBX1Tr+pIuCrG/Ud49SBqeS5aMJGVwiSd7o1n
dhU2Sz3Q60DwJEL1VenQHiVYlWWtqXBThe9ggqRPnCfsCRTP8qifKkjk45zWPcpN
-----END CERTIFICATE-----

15
test_key.pem

@ -1,15 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDx3wdzpq2rvwm3Ucun1qAD/ClB+wW+RhR1nVix286QvaNqePAd
CAwwLL82NqXcVQRbQ4s95splQnwvjgkFdKVXFTjPKKJI5aV3wSRN61EBVPdYpCre
535yfG/uDysZFCnVQdnCZ1tnXAR8BirxCNjHqbVyIyBGjsNoNCEPb2R35QIDAQAB
AoGBAJNem9C4ftrFNGtQ2DB0Udz7uDuucepkErUy4MbFsc947GfENjDKJXr42Kx0
kYx09ImS1vUpeKpH3xiuhwqe7tm4FsCBg4TYqQle14oxxm7TNeBwwGC3OB7hiokb
aAjbPZ1hAuNs6ms3Ybvvj6Lmxzx42m8O5DXCG2/f+KMvaNUhAkEA/ekrOsWkNoW9
2n3m+msdVuxeek4B87EoTOtzCXb1dybIZUVv4J48VAiM43hhZHWZck2boD/hhwjC
M5NWd4oY6QJBAPPcgBVNdNZSZ8hR4ogI4nzwWrQhl9MRbqqtfOn2TK/tjMv10ALg
lPmn3SaPSNRPKD2hoLbFuHFERlcS79pbCZ0CQQChX3PuIna/gDitiJ8oQLOg7xEM
wk9TRiDK4kl2lnhjhe6PDpaQN4E4F0cTuwqLAoLHtrNWIcOAQvzKMrYdu1MhAkBm
Et3qDMnjDAs05lGT72QeN90/mPAcASf5eTTYGahv21cb6IBxM+AnwAPpqAAsHhYR
9h13Y7uYbaOjvuF23LRhAkBoI9eaSMn+l81WXOVUHnzh3ZwB4GuTyxMXXNOhuiFd
0z4LKAMh99Z4xQmqSoEkXsfM4KPpfhYjF/bwIcP5gOei
-----END RSA PRIVATE KEY-----

178
verushash.cc

@ -0,0 +1,178 @@
#include <node.h>
#include <node_events.h>
#include <assert.h>
#include <string.h>
using namespace v8;
using namespace node;
void hex_encode(unsigned char *md_value, int md_len, char** md_hexdigest, int* md_hex_len) {
*md_hex_len = (2*(md_len));
*md_hexdigest = (char *) malloc(*md_hex_len + 1);
for(int i = 0; i < md_len; i++) {
sprintf((char *)(*md_hexdigest + (i*2)), "%02x", md_value[i]);
}
}
#define hex2i(c) ((c) <= '9' ? ((c) - '0') : (c) <= 'Z' ? ((c) - 'A' + 10) : ((c) - 'a' + 10))
void hex_decode(unsigned char *input, int length, char** buf64, int* buf64_len) {
*buf64_len = (length/2);
*buf64 = (char*) malloc(length/2 + 1);
char *b = *buf64;
for(int i = 0; i < length-1; i+=2) {
b[i/2] = (hex2i(input[i])<<4) | (hex2i(input[i+1]));
}
}
class Hash : public ObjectWrap {
public:
static void
Initialize (v8::Handle<v8::Object> target)
{
HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(t, "init", HashInit);
NODE_SET_PROTOTYPE_METHOD(t, "update", HashUpdate);
NODE_SET_PROTOTYPE_METHOD(t, "digest", HashDigest);
target->Set(String::NewSymbol("Hash"), t->GetFunction());
}
bool HashInit (const char* hashType)
{
initialised = true;
return true;
}
int HashUpdate(char* data, int len) {
if (!initialised)
return 0;
// put Hash here
return 1;
}
int HashDigest(unsigned char** md_value, unsigned int *md_len) {
if (!initialised)
return 0;
// finalize and return value here
return 1;
}
protected:
static Handle<Value>
New (const Arguments& args)
{
HandleScope scope;
Hash *hash = new Hash();
hash->Wrap(args.This());
return args.This();
}
static Handle<Value>
HashInit(const Arguments& args) {
Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
HandleScope scope;
if (args.Length() == 0 || !args[0]->IsString()) {
return ThrowException(String::New("Must give hashtype string as argument"));
}
String::Utf8Value hashType(args[0]->ToString());
bool r = hash->HashInit(*hashType);
return args.This();
}
static Handle<Value>
HashUpdate(const Arguments& args) {
Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
HandleScope scope;
enum encoding enc = ParseEncoding(args[1]);
ssize_t len = DecodeBytes(args[0], enc);
if (len < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
return ThrowException(exception);
}
char* buf = new char[len];
ssize_t written = DecodeWrite(buf, len, args[0], enc);
assert(written == len);
int r = hash->HashUpdate(buf, len);
return args.This();
}
static Handle<Value>
HashDigest(const Arguments& args) {
Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
HandleScope scope;
unsigned char* md_value;
unsigned int md_len;
char* md_hexdigest;
int md_hex_len;
Local<Value> outString ;
int r = hash->HashDigest(&md_value, &md_len);
if (md_len == 0 || r == 0) {
return scope.Close(String::New(""));
}
if (args.Length() == 0 || !args[0]->IsString()) {
// Binary
outString = Encode(md_value, md_len, BINARY);
} else {
String::Utf8Value encoding(args[0]->ToString());
if (strcasecmp(*encoding, "hex") == 0) {
// Hex encoding
hex_encode(md_value, md_len, &md_hexdigest, &md_hex_len);
outString = Encode(md_hexdigest, md_hex_len, BINARY);
free(md_hexdigest);
} else if (strcasecmp(*encoding, "binary") == 0) {
outString = Encode(md_value, md_len, BINARY);
} else {
fprintf(stderr, "verushash-node : Hash .digest encoding "
"can be binary or hex\n");
}
}
free(md_value);
return scope.Close(outString);
}
Hash () : ObjectWrap (), vh()
{
initialised = false;
}
~Hash ()
{
}
private:
CVerusHash vh;
bool initialised;
};
extern "C" void
init (Handle<Object> target)
{
HandleScope scope;
Hash::Initialize(target);
}

23
wscript

@ -4,7 +4,7 @@ from os.path import exists
srcdir = "."
blddir = "build"
VERSION = "0.0.3"
VERSION = "0.0.5"
def set_options(opt):
opt.tool_options("compiler_cxx")
@ -15,21 +15,24 @@ def configure(conf):
conf.check_tool("compiler_cc")
conf.check_tool("node_addon")
conf.check(lib='ssl', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='OPENSSL')
conf.check(lib='ssl', libpath=['/usr/lib', '/usr/local/lib'])
def build(bld):
obj = bld.new_task_gen("cxx", "shlib", "node_addon")
obj.target = "crypto"
obj.source = "crypto.cc"
obj.uselib = "OPENSSL"
obj.target = "verushash"
obj.include = "verus_hash.h"
obj.include = "haraka.h"
obj.include = "haraka_port.h"
obj.source = "verus_hash.cpp"
obj.source = "haraka.c"
obj.source = "haraka_port.c"
obj.source = "verushash.cc"
def shutdown():
# HACK to get crypto.node out of build directory.
# better way to do this?
if Options.commands['clean']:
if exists('crypto.node'): unlink('crypto.node')
if exists('verushash.node'): unlink('verushash.node')
else:
if exists('build/default/crypto.node') and not exists('crypto.node'):
symlink('build/default/crypto.node', 'crypto.node')
if exists('build/default/verushash.node') and not exists('verushash.node'):
symlink('build/default/verushash.node', 'verushash.node')

Loading…
Cancel
Save