Skip to content

Commit

Permalink
provenance: more buffer usage + spec test
Browse files Browse the repository at this point in the history
  • Loading branch information
astro committed Jun 18, 2011
1 parent 5e8060d commit 4516c37
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 20 deletions.
31 changes: 13 additions & 18 deletions lib/ostatus/salmon.js
Expand Up @@ -27,11 +27,9 @@ var Sys = require('sys'),
Flow = require('flow'),
Util = require('util'),
Http = require('./http.js'),
Xml = require('o3-xml');
Xml = require('o3-xml'),
Path = require('path'),
Mu = require('mu');
Base64 = require('base64');
Crypto = require('crypto');
Mu = require('mu'),
Buffer = require('buffer').Buffer;

/*
Expand Down Expand Up @@ -99,6 +97,15 @@ function xmlToJs(body, callback) {
}
}

function _grabKey(jrd) {
if (jrd != null && jrd.links != undefined) {
for(var i=0; i<jrd.links.length; i++) {
var link = jrd.links[i];
if (link.rel == "magic-public-key") return link;
}
}
}

// Assemble the signature base string
function baseString(data, data_type, encoding, alg) {
return [data,
Expand Down Expand Up @@ -130,7 +137,6 @@ function verifySignature(me, sig, pubKey) {
var m = baseString(me.data, me.data_type,
me.encoding || 'base64url',
me.alg || 'RSA-SHA256');
sig = base64url_decode(sig);

var match;
if ((match = pubKey.match(/^RSA\.([^\.]+)\.([^\.]+)$/)))
Expand All @@ -142,24 +148,13 @@ function verifySignature(me, sig, pubKey) {
throw TypeError('Invalid public key');
}

function _grabKey(jrd) {
if (jrd != null && jrd.links != undefined) {
for(var i=0; i<jrd.links.length; i++) {
var link = jrd.links[i];
if (link.rel == "magic-public-key") return link;
}
}
}

//From: https://github.com/ptarjan/base64url/blob/master/node.js
function base64url_decode(input) {
return Base64.decode(input.replace(/-/g, '+').replace(/_/g, '/'));
return new Buffer(input.toString().replace(/-/g, '+').replace(/_/g, '/'), 'base64');
}

// Encode to Base64url and removing padding (as per salmon spec)
function base64url_encode(input) {
var buf = new Buffer(input);
return Base64.encode(buf).replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
return input.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
}

exports.unpack = unpack;
Expand Down
24 changes: 22 additions & 2 deletions src/provenance.cc
Expand Up @@ -2,10 +2,25 @@
#include <node_buffer.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <cstring>

using namespace v8;
using namespace node;

// http://sambro.is-super-awesome.com/2011/03/03/creating-a-proper-buffer-in-a-node-c-addon/
static Handle<Value> makeBuffer(unsigned char *data, int length) {
HandleScope scope;

Buffer *slowBuffer = Buffer::New(length);
memcpy(Buffer::Data(slowBuffer), data, length);
Local<Object> globalObj = Context::GetCurrent()->Global();
Local<Function> bufferConstructor = Local<Function>::Cast(globalObj->Get(String::New("Buffer")));
Handle<Value> constructorArgs[3] = { slowBuffer->handle_, Integer::New(length), Integer::New(0) };
Local<Object> actualBuffer = bufferConstructor->NewInstance(3, constructorArgs);

return scope.Close(actualBuffer);
}

/**
* Do not forget to call BIO_free() after use
*/
Expand Down Expand Up @@ -49,7 +64,7 @@ static Handle<Value> bnToBinary(BIGNUM *bn) {
unsigned char *data = new unsigned char[BN_num_bytes(bn)];
int len = BN_bn2bin(bn, data);
if (len > 0) {
result = Encode(data, len);
result = makeBuffer(data, len);
} else {
result = Null();
}
Expand Down Expand Up @@ -166,7 +181,7 @@ static Handle<Value> SignRSASHA256(const Arguments &args) {
Local<Value> exception = Exception::Error(String::New("Cannot sign"));
return ThrowException(exception);
}
Local<Value> sigResult = Encode(sig, sigLen);
Handle<Value> sigResult = makeBuffer(sig, sigLen);

EVP_PKEY_free(pkey);
delete[] sig;
Expand All @@ -175,6 +190,11 @@ static Handle<Value> SignRSASHA256(const Arguments &args) {
return scope.Close(sigResult);
}

/**
* @param Message
* @param Signature to verify
* @param Public key { n: Buffer, e: Buffer }
*/
static Handle<Value> VerifyRSASHA256(const Arguments &args) {
HandleScope scope;

Expand Down
29 changes: 29 additions & 0 deletions tests/test_salmon.js
Expand Up @@ -37,6 +37,35 @@ Vows.describe('Salmon').addBatch({
}
}
}
},

'spec example': {
'should work': {
topic: function() {
var pubKey = "RSA.mVgY8RN6URBTstndvmUUPb4UZTdwvwmddSKE5z_jvKUEK6yk1u3rrC9yN8k6FilGj9K0eeUPe2hf4Pj-5CmHww.AQAB";
var sig = "EvGSD2vi8qYcveHnb-rrlok07qnCXjn8YSeCDDXlbhILSabgvNsPpbe76up8w63i2fWHvLKJzeGLKfyHg8ZomQ";
var data = "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4KPGVudHJ5IHhtbG5zPS" +
"dodHRwOi8vd3d3LnczLm9yZy8yMDA1L0F0b20nPgogIDxpZD50YWc6ZXhhbXBsZS5jb20s" +
"MjAwOTpjbXQtMC40NDc3NTcxODwvaWQ-ICAKICA8YXV0aG9yPjxuYW1lPnRlc3RAZXhhbX" +
"BsZS5jb208L25hbWUPHVyaT5hY2N0OmpwYW56ZXJAZ29vZ2xlLmNvbTwvdXJpPjwvYXV0a" +
"G9yPgogIDx0aHI6aW4tcmVwbHktdG8geG1sbnM6dGhyPSdodHRwOi8vcHVybC5vcmcvc3l" +
"uZGljYXRpb24vdGhyZWFkLzEuMCcKICAgICAgcmVmPSd0YWc6YmxvZ2dlci5jb20sMTk5O" +
"TpibG9nLTg5MzU5MTM3NDMxMzMxMjczNy5wb3N0LTM4NjE2NjMyNTg1Mzg4NTc5NTQnPnR" +
"hZzpibG9nZ2VyLmNvbSwxOTk5OmJsb2ctODkzNTkxMzc0MzEzMzEyNzM3LnBvc3QtMzg2M" +
"TY2MzI1ODUzODg1Nzk1NAogIDwvdGhyOmluLXJlcGx5LXRvPgogIDxjb250ZW50PlNhbG1" +
"vbiBzd2ltIHVwc3RyZWFtITwvY29udGVudD4KICA8dGl0bGUU2FsbW9uIHN3aW0gdXBzdH" +
"JlYW0hPC90aXRsZT4KICA8dXBkYXRlZD4yMDA5LTEyLTE4VDIwOjA0OjAzWjwvdXBkYXRl" +
"ZD4KPC9lbnRyeT4KICAgIA";
var data_type = "application/atom+xml";
this.verified = Salmon.verifySignature({ data: Salmon.base64url_decode(data),
data_type: data_type },
Salmon.base64url_decode(sig), pubKey);
this.callback();
},
verifies: function() {
Assert.ok(this.verified);
}
}
}

}).run();

0 comments on commit 4516c37

Please sign in to comment.