Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add RSA-SHA1 support #121

Merged
merged 1 commit into from

4 participants

@knechtandreas

This builds on a fork from https://github.com/wraithgar/node-oauth. All I did was to basically add a test that ensures creating a signature with RSA-SHA1 works and that this signature can then be verified with a matching public key.

(See comments in #43).

I also verified that this works against a working OAuth service provider using RSA-SHA1 (Atlassian JIRA).

Andreas Knecht Added RSA-SHA1 signature method based on the fork from https://github…
….com/wraithgar/node-oauth.  Added test that uses the RSA-SHA1 method and verifies the signature using a public key.
635ee2c
@knechtandreas knechtandreas referenced this pull request
Closed

Adds RSA-SHA1 Support #43

@wraithgar

Thanks for getting this put together.

@rmanalan

Hello all. Any reason why this hasn't been merged in?

@ciaranj ciaranj merged commit d228aeb into from
@ciaranj
Owner

Merged. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 20, 2012
  1. Added RSA-SHA1 signature method based on the fork from https://github…

    Andreas Knecht authored
    ….com/wraithgar/node-oauth.  Added test that uses the RSA-SHA1 method and verifies the signature using a public key.
This page is out of date. Refresh to see the latest.
Showing with 52 additions and 3 deletions.
  1. +12 −2 lib/oauth.js
  2. +40 −1 tests/oauth.js
View
14 lib/oauth.js
@@ -13,6 +13,9 @@ exports.OAuth= function(requestUrl, accessUrl, consumerKey, consumerSecret, vers
this._accessUrl= accessUrl;
this._consumerKey= consumerKey;
this._consumerSecret= this._encodeData( consumerSecret );
+ if (signatureMethod == "RSA-SHA1") {
+ this._privateKey = consumerSecret;
+ }
this._version= version;
if( authorize_callback === undefined ) {
this._authorize_callback= "oob";
@@ -21,7 +24,7 @@ exports.OAuth= function(requestUrl, accessUrl, consumerKey, consumerSecret, vers
this._authorize_callback= authorize_callback;
}
- if( signatureMethod != "PLAINTEXT" && signatureMethod != "HMAC-SHA1")
+ if( signatureMethod != "PLAINTEXT" && signatureMethod != "HMAC-SHA1" && signatureMethod != "RSA-SHA1")
throw new Error("Un-supported signature method: " + signatureMethod )
this._signatureMethod= signatureMethod;
this._nonceSize= nonceSize || 32;
@@ -40,9 +43,12 @@ exports.OAuthEcho= function(realm, verify_credentials, consumerKey, consumerSecr
this._verifyCredentials = verify_credentials;
this._consumerKey= consumerKey;
this._consumerSecret= this._encodeData( consumerSecret );
+ if (signatureMethod == "RSA-SHA1") {
+ this._privateKey = consumerSecret;
+ }
this._version= version;
- if( signatureMethod != "PLAINTEXT" && signatureMethod != "HMAC-SHA1")
+ if( signatureMethod != "PLAINTEXT" && signatureMethod != "HMAC-SHA1" && signatureMethod != "RSA-SHA1")
throw new Error("Un-supported signature method: " + signatureMethod );
this._signatureMethod= signatureMethod;
this._nonceSize= nonceSize || 32;
@@ -197,6 +203,10 @@ exports.OAuth.prototype._createSignature= function(signatureBase, tokenSecret) {
if( this._signatureMethod == "PLAINTEXT" ) {
hash= key;
}
+ else if (this._signatureMethod == "RSA-SHA1") {
+ key = this._privateKey || "";
+ hash= crypto.createSign("RSA-SHA1").update(signatureBase).sign(key, 'base64');
+ }
else {
if( crypto.Hmac ) {
hash = crypto.createHmac("sha1", key).update(signatureBase).digest("base64");
View
41 tests/oauth.js
@@ -2,7 +2,8 @@ var vows = require('vows'),
assert = require('assert'),
events = require('events'),
OAuth= require('../lib/oauth').OAuth,
- OAuthEcho= require('../lib/oauth').OAuthEcho;
+ OAuthEcho= require('../lib/oauth').OAuthEcho,
+ crypto = require('crypto');
var DummyResponse =function( statusCode ) {
this.statusCode= statusCode;
@@ -23,6 +24,30 @@ DummyRequest.prototype.end= function(){
this.response.emit('end');
}
+//Valid RSA keypair used to test RSA-SHA1 signature method
+var RsaPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\n" +
+"MIICXQIBAAKBgQDizE4gQP5nPQhzof/Vp2U2DDY3UY/Gxha2CwKW0URe7McxtnmE\n" +
+"CrZnT1n/YtfrrCNxY5KMP4o8hMrxsYEe05+1ZGFT68ztms3puUxilU5E3BQMhz1t\n" +
+"JMJEGcTt8nZUlM4utli7fHgDtWbhvqvYjRMGn3AjyLOfY8XZvnFkGjipvQIDAQAB\n" +
+"AoGAKgk6FcpWHOZ4EY6eL4iGPt1Gkzw/zNTcUsN5qGCDLqDuTq2Gmk2t/zn68VXt\n" +
+"tVXDf/m3qN0CDzOBtghzaTZKLGhnSewQ98obMWgPcvAsb4adEEeW1/xigbMiaW2X\n" +
+"cu6GhZxY16edbuQ40LRrPoVK94nXQpj8p7w4IQ301Sm8PSECQQD1ZlOj4ugvfhEt\n" +
+"exi4WyAaM45fylmN290UXYqZ8SYPI/VliDytIlMfyq5Rv+l+dud1XDPrWOQ0ImgV\n" +
+"HJn7uvoZAkEA7JhHNmHF9dbdF9Koj86K2Cl6c8KUu7U7d2BAuB6pPkt8+D8+y4St\n" +
+"PaCmN4oP4X+sf5rqBYoXywHlqEei2BdpRQJBAMYgR4cZu7wcXGIL8HlnmROObHSK\n" +
+"OqN9z5CRtUV0nPW8YnQG+nYOMG6KhRMbjri750OpnYF100kEPmRNI0VKQIECQE8R\n" +
+"fQsRleTYz768ahTVQ9WF1ySErMwmfx8gDcD6jjkBZVxZVpURXAwyehopi7Eix/VF\n" +
+"QlxjkBwKIEQi3Ks297kCQQCL9by1bueKDMJO2YX1Brm767pkDKkWtGfPS+d3xMtC\n" +
+"KJHHCqrS1V+D5Q89x5wIRHKxE5UMTc0JNa554OxwFORX\n" +
+"-----END RSA PRIVATE KEY-----";
+
+var RsaPublicKey = "-----BEGIN PUBLIC KEY-----\n" +
+"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDizE4gQP5nPQhzof/Vp2U2DDY3\n" +
+"UY/Gxha2CwKW0URe7McxtnmECrZnT1n/YtfrrCNxY5KMP4o8hMrxsYEe05+1ZGFT\n" +
+"68ztms3puUxilU5E3BQMhz1tJMJEGcTt8nZUlM4utli7fHgDtWbhvqvYjRMGn3Aj\n" +
+"yLOfY8XZvnFkGjipvQIDAQAB\n" +
+"-----END PUBLIC KEY-----";
+
vows.describe('OAuth').addBatch({
'When generating the signature base string described in http://oauth.net/core/1.0/#sig_base_example': {
topic: new OAuth(null, null, null, null, null, null, "HMAC-SHA1"),
@@ -32,6 +57,20 @@ vows.describe('OAuth').addBatch({
assert.equal( result, "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal");
}
},
+ 'When generating the signature with RSA-SHA1': {
+ topic: new OAuth(null, null, null, RsaPrivateKey, null, null, "RSA-SHA1"),
+ 'we get a valid oauth signature': function (oa) {
+ var signatureBase = "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal";
+ var oauthSignature = oa._createSignature(signatureBase, "xyz4992k83j47x0b");
+
+ assert.equal( oauthSignature, "qS4rhWog7GPgo4ZCJvUdC/1ZAax/Q4Ab9yOBvgxSopvmKUKp5rso+Zda46GbyN2hnYDTiA/g3P/d/YiPWa454BEBb/KWFV83HpLDIoqUUhJnlXX9MqRQQac0oeope4fWbGlfTdL2PXjSFJmvfrzybERD/ZufsFtVrQKS3QBpYiw=");
+
+ //now check that given the public key we can verify this signature
+ var verifier = crypto.createVerify("RSA-SHA1").update(signatureBase);
+ var valid = verifier.verify(RsaPublicKey, oauthSignature, 'base64');
+ assert.ok( valid, "Signature could not be verified with RSA public key");
+ }
+ },
'When generating the signature base string with PLAINTEXT': {
topic: new OAuth(null, null, null, null, null, null, "PLAINTEXT"),
'we get the expected result string': function (oa) {
Something went wrong with that request. Please try again.