Permalink
Browse files

Provenance.verifyRSASHA256

  • Loading branch information...
1 parent 99d4d40 commit 5e8060d9717ac3b2dc51028e22aa692e8e8fe7cb @astro committed Jun 10, 2011
Showing with 89 additions and 7 deletions.
  1. +12 −2 lib/ostatus/salmon.js
  2. +64 −1 src/provenance.cc
  3. +13 −4 tests/test_salmon.js
View
@@ -127,9 +127,19 @@ function generateSignature(me, privKey) {
}
function verifySignature(me, sig, pubKey) {
- var m = baseString(me.data, me.data_type, me.encoding || 'base64url', me.alg);
+ var m = baseString(me.data, me.data_type,
+ me.encoding || 'base64url',
+ me.alg || 'RSA-SHA256');
sig = base64url_decode(sig);
- return Provenance.verifyRSASHA256(m, sig, pubKey);
+
+ var match;
+ if ((match = pubKey.match(/^RSA\.([^\.]+)\.([^\.]+)$/)))
+ return Provenance.verifyRSASHA256(m, sig,
+ { n: base64url_decode(match[1]),
+ e: base64url_decode(match[2])
+ });
+ else
+ throw TypeError('Invalid public key');
}
function _grabKey(jrd) {
View
@@ -175,6 +175,68 @@ static Handle<Value> SignRSASHA256(const Arguments &args) {
return scope.Close(sigResult);
}
+static Handle<Value> VerifyRSASHA256(const Arguments &args) {
+ HandleScope scope;
+
+ if (args.Length() != 3) {
+ Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
+ return ThrowException(exception);
+ }
+ Handle<Value> m = args[0];
+ Handle<Value> sig = args[1];
+ Handle<Object> pubKey = args[2]->ToObject();
+
+ /* Prepare verification */
+ const EVP_MD *md = EVP_get_digestbyname("RSA-SHA256");
+ if (!md) {
+ Local<Value> exception = Exception::Error(String::New("No RSA-SHA256 message digest"));
+ return ThrowException(exception);
+ }
+ EVP_MD_CTX mdctx;
+ EVP_MD_CTX_init(&mdctx);
+ EVP_VerifyInit_ex(&mdctx, md, NULL);
+
+
+ /* Write data */
+ /* TODO: for buffers, this could be zero-copy */
+ ssize_t mLen = DecodeBytes(m);
+ char *mBuf = new char[mLen];
+ mLen = DecodeWrite(mBuf, mLen, m);
+ EVP_VerifyUpdate(&mdctx, mBuf, mLen);
+ delete[] mBuf;
+
+ /* Prepare key */
+ RSA *rsa = RSA_new();
+ Handle<Value> n = pubKey->Get(String::NewSymbol("n"));
+ rsa->n = binaryToBn(n);
+ Handle<Value> e = pubKey->Get(String::NewSymbol("e"));
+ rsa->e = binaryToBn(e);
+ EVP_PKEY *pkey = EVP_PKEY_new();
+ EVP_PKEY_set1_RSA(pkey, rsa);
+
+ /* Pass sig */
+ /* TODO: for buffers, this could be zero-copy */
+ ssize_t sigLen = DecodeBytes(sig);
+ char *sigBuf = new char[sigLen];
+ sigLen = DecodeWrite(sigBuf, sigLen, sig);
+ int status = EVP_VerifyFinal(&mdctx, (unsigned char *)sigBuf, sigLen, pkey);
+ delete[] sigBuf;
+
+ EVP_PKEY_free(pkey);
+
+ switch(status) {
+ case 1:
+ return scope.Close(True());
+ break;
+ case 0:
+ return scope.Close(False());
+ break;
+ default:
+ Local<Value> exception = Exception::Error(String::New("Verification error"));
+ return ThrowException(exception);
+ }
+}
+
extern "C" void
init (Handle<Object> target)
{
@@ -183,6 +245,7 @@ init (Handle<Object> target)
OpenSSL_add_all_digests();
OpenSSL_add_all_algorithms();
- NODE_SET_METHOD(target, "signRSASHA256", SignRSASHA256);
NODE_SET_METHOD(target, "generate", Generate);
+ NODE_SET_METHOD(target, "signRSASHA256", SignRSASHA256);
+ NODE_SET_METHOD(target, "verifyRSASHA256", VerifyRSASHA256);
}
View
@@ -18,13 +18,22 @@ Vows.describe('Salmon').addBatch({
},
'can be used to sign': {
topic: function() {
- var me = { data: 'Hello World',
- data_type: 'application/test' };
- this.sig = Salmon.generateSignature(me, this.key.private);
+ this.me = { data: 'Hello World',
+ data_type: 'application/test' };
+ this.sig = Salmon.generateSignature(this.me, this.key.private);
this.callback();
},
'signature generated': function() {
- console.log(this.sig.length);
+ Assert.equal(this.sig.length, 256);
+ },
+ 'can be verified': {
+ topic: function() {
+ this.verified = Salmon.verifySignature(this.me, this.sig, this.key.public);
+ this.callback();
+ },
+ 'verification successful': function() {
+ Assert.ok(this.verified);
+ }
}
}
}

0 comments on commit 5e8060d

Please sign in to comment.