Fix authorizations controller and app_config specs, require 2048 bit keys. We're now using config/application.yml.example in the test env.
This commit is contained in:
parent
c91cf6f38c
commit
052adc3213
8 changed files with 80 additions and 42 deletions
|
|
@ -60,22 +60,23 @@ class AuthorizationsController < ApplicationController
|
||||||
|
|
||||||
# @param [String] enc_signed_string A Base64 encoded string with app_url;pod_url;time;nonce
|
# @param [String] enc_signed_string A Base64 encoded string with app_url;pod_url;time;nonce
|
||||||
# @param [String] sig A Base64 encoded signature of the decoded signed_string with public_key.
|
# @param [String] sig A Base64 encoded signature of the decoded signed_string with public_key.
|
||||||
# @param [String] public_key The application's public key to verify sig with.
|
# @param [OpenSSL::PKey::RSA] public_key The application's public key to verify sig with.
|
||||||
|
# @return [String] 'ok' or an error message.
|
||||||
def verify( enc_signed_string, sig, public_key)
|
def verify( enc_signed_string, sig, public_key)
|
||||||
signed_string = Base64.decode64(enc_signed_string)
|
signed_string = Base64.decode64(enc_signed_string)
|
||||||
split = signed_string.split(';')
|
split = signed_string.split(';')
|
||||||
time = split[2]
|
time = split[2]
|
||||||
nonce = split[3]
|
nonce = split[3]
|
||||||
|
|
||||||
return 'blank public key' if public_key.blank?
|
return 'blank public key' if public_key.n.nil?
|
||||||
|
return 'key too small, use at least 2048 bits' if public_key.n.num_bits < 2048
|
||||||
return "invalid time" unless valid_time?(time)
|
return "invalid time" unless valid_time?(time)
|
||||||
return 'invalid nonce' unless valid_nonce?(nonce)
|
return 'invalid nonce' unless valid_nonce?(nonce)
|
||||||
return 'invalid signature' unless verify_signature(signed_string, Base64.decode64(sig), public_key)
|
return 'invalid signature' unless verify_signature(signed_string, Base64.decode64(sig), public_key)
|
||||||
'ok'
|
'ok'
|
||||||
end
|
end
|
||||||
|
|
||||||
def verify_signature(challenge, signature, serialized_pub_key)
|
def verify_signature(challenge, signature, public_key)
|
||||||
public_key = OpenSSL::PKey::RSA.new(serialized_pub_key)
|
|
||||||
public_key.verify(OpenSSL::Digest::SHA256.new, signature, challenge)
|
public_key.verify(OpenSSL::Digest::SHA256.new, signature, challenge)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,11 @@ require 'uri'
|
||||||
|
|
||||||
class AppConfig < Settingslogic
|
class AppConfig < Settingslogic
|
||||||
|
|
||||||
source File.join(Rails.root, "config", "application.yml")
|
if Rails.env == 'test'
|
||||||
|
source File.join(Rails.root, "config", "application.yml.example")
|
||||||
|
else
|
||||||
|
source File.join(Rails.root, "config", "application.yml")
|
||||||
|
end
|
||||||
namespace Rails.env
|
namespace Rails.env
|
||||||
|
|
||||||
def self.load!
|
def self.load!
|
||||||
|
|
@ -94,4 +98,4 @@ HELP
|
||||||
end
|
end
|
||||||
return @@pod_uri
|
return @@pod_uri
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,5 @@ gem 'json'
|
||||||
gem 'shotgun'
|
gem 'shotgun'
|
||||||
gem 'sqlite3'
|
gem 'sqlite3'
|
||||||
gem 'activerecord', '3.0.3'
|
gem 'activerecord', '3.0.3'
|
||||||
gem 'diaspora-client', :path => "~/work/diaspora-client"
|
gem 'diaspora-client', :path => "~/workspace/diaspora-client"
|
||||||
#:git => 'git@github.com:diaspora/diaspora-client.git'
|
#:git => 'git@github.com:diaspora/diaspora-client.git'
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
PATH
|
PATH
|
||||||
remote: ~/work/diaspora-client
|
remote: ~/workspace/diaspora-client
|
||||||
specs:
|
specs:
|
||||||
diaspora-client (0.0.0)
|
diaspora-client (0.0.0)
|
||||||
activerecord
|
activerecord
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,27 @@
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
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
|
||||||
-----END RSA PRIVATE KEY-----
|
-----END RSA PRIVATE KEY-----
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
-----BEGIN PUBLIC KEY-----
|
-----BEGIN RSA PUBLIC KEY-----
|
||||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6PThqopA0Sv1ZrWp+wKz6SPQw
|
MIIBCgKCAQEA6YpLa9kYE0Uh/9fiXOFs8i64ZMR3Nyw4o7YB/X6V1QV195CoXoLr
|
||||||
WzS2IEGRV1eBE2LEvMk5K2MKjZqDF6SeolCPQsDww03qIxbtzXiVFtjBaiDw+fLp
|
ayFZqDc1N+WTjKurHISIqXsOjOnpHfrbptXri7qXwMyLDAtgSd+NlTWSnJXJlP03
|
||||||
bnX3VcfoMlfV3IKMPjD8eFUE2ke3tJzHeXLfXhHq5ubX1PrXcsNwHeNrtvviv9G2
|
VrdoUp+dtfKTakhDwBFNrdB+vCAzPve6+6ZEMQZGF+YZBfq7VEPG4iKZQ34C3lZI
|
||||||
BhYMjwi49T0YS27rhwIDAQAB
|
fEZlpZQak5tUNWXS5V9uBxAEi1KgoxdQQR3uEctLfQS/QQZ4SNTNVMJsLm6cxHVh
|
||||||
-----END PUBLIC KEY-----
|
Q5ekXqtpfjM328T8/B+EU4qv+YC2wlHuwL7ztT6/m5rcVtmeunuQVkQueOEZbr6S
|
||||||
|
6X4du2+4q1/bkmnAS0f28ZcGlnScOz+XqQIDAQAB
|
||||||
|
-----END RSA PUBLIC KEY-----
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,13 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe AuthorizationsController do
|
describe AuthorizationsController do
|
||||||
|
RSA = OpenSSL::PKey::RSA
|
||||||
|
|
||||||
|
before :all do
|
||||||
|
@private_key = RSA.generate(2048)
|
||||||
|
@public_key = @private_key.public_key
|
||||||
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in :user, alice
|
sign_in :user, alice
|
||||||
@controller.stub(:current_user).and_return(alice)
|
@controller.stub(:current_user).and_return(alice)
|
||||||
|
|
@ -22,11 +29,13 @@ describe AuthorizationsController do
|
||||||
"description" => "The best way to chub.",
|
"description" => "The best way to chub.",
|
||||||
"homepage_url" => "http://chubbi.es/",
|
"homepage_url" => "http://chubbi.es/",
|
||||||
"icon_url" => "#",
|
"icon_url" => "#",
|
||||||
'public_key' => 'public_key!'
|
"permissions_overview" => "I will use the permissions this way!",
|
||||||
}.to_json
|
}
|
||||||
|
|
||||||
|
packaged_manifest = {:public_key => @public_key.export, :jwt => JWT.encode(manifest, @private_key, "RS256")}.to_json
|
||||||
|
|
||||||
stub_request(:get, "http://chubbi.es/manifest.json").
|
stub_request(:get, "http://chubbi.es/manifest.json").
|
||||||
to_return(:status => 200, :body => manifest, :headers => {})
|
to_return(:status => 200, :body => packaged_manifest, :headers => {})
|
||||||
|
|
||||||
@params_hash = {:type => 'client_associate', :manifest_url => "http://chubbi.es/manifest.json" }
|
@params_hash = {:type => 'client_associate', :manifest_url => "http://chubbi.es/manifest.json" }
|
||||||
end
|
end
|
||||||
|
|
@ -51,7 +60,11 @@ describe AuthorizationsController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'verifies the signable string validity(time,nonce,sig)' do
|
it 'verifies the signable string validity(time,nonce,sig)' do
|
||||||
@controller.should_receive(:verify).with('signed_string', 'sig', 'public_key!')
|
@controller.should_receive(:verify){|a,b,c|
|
||||||
|
a.should == 'signed_string'
|
||||||
|
b.should == 'sig'
|
||||||
|
c.export.should == @public_key.export
|
||||||
|
}
|
||||||
post :token, @params_hash.merge!({:signed_string => 'signed_string', :signature => 'sig'})
|
post :token, @params_hash.merge!({:signed_string => 'signed_string', :signature => 'sig'})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -95,40 +108,44 @@ describe AuthorizationsController do
|
||||||
end
|
end
|
||||||
it 'checks for valid time' do
|
it 'checks for valid time' do
|
||||||
@controller.should_receive(:valid_time?).with(@time.to_i.to_s)
|
@controller.should_receive(:valid_time?).with(@time.to_i.to_s)
|
||||||
@controller.verify(Base64.encode64(@signable_string), @sig, 'public_key!')
|
@controller.verify(Base64.encode64(@signable_string), @sig, @public_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'checks the signature' do
|
it 'checks the signature' do
|
||||||
@controller.should_receive(:verify_signature).with(@signable_string, 'sig', 'public_key!')
|
@controller.should_receive(:verify_signature).with(@signable_string, 'sig', @public_key)
|
||||||
@controller.verify(Base64.encode64(@signable_string), @sig, 'public_key!')
|
@controller.verify(Base64.encode64(@signable_string), @sig, @public_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'checks for valid nonce' do
|
it 'checks for valid nonce' do
|
||||||
@controller.should_receive(:valid_nonce?).with(@nonce)
|
@controller.should_receive(:valid_nonce?).with(@nonce)
|
||||||
@controller.verify(Base64.encode64(@signable_string), @sig, 'public_key!')
|
@controller.verify(Base64.encode64(@signable_string), @sig, @public_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'checks for public key' do
|
it 'checks for public key' do
|
||||||
@controller.verify(Base64.encode64(@signable_string), @sig, '').should == "blank public key"
|
@controller.verify(Base64.encode64(@signable_string), @sig, RSA.new()).should == "blank public key"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'checks key size' do
|
||||||
|
short_key = RSA.generate(100)
|
||||||
|
RSA.stub!(:new).and_return(short_key)
|
||||||
|
@controller.verify(Base64.encode64(@signable_string), @sig, RSA.generate(100).public_key).
|
||||||
|
should == "key too small, use at least 2048 bits"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#verify_signature' do
|
describe '#verify_signature' do
|
||||||
before do
|
before do
|
||||||
@private_key = OpenSSL::PKey::RSA.new(File.read(Rails.root + "spec/chubbies/chubbies.private.pem"))
|
|
||||||
|
|
||||||
@sig = @private_key.sign(OpenSSL::Digest::SHA256.new, @signable_string)
|
@sig = @private_key.sign(OpenSSL::Digest::SHA256.new, @signable_string)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns true if the signature is valid' do
|
it 'returns true if the signature is valid' do
|
||||||
@public_key = File.read(Rails.root + "spec/chubbies/chubbies.public.pem")
|
|
||||||
@controller.verify_signature(@signable_string, @sig, @public_key).should be_true
|
@controller.verify_signature(@signable_string, @sig, @public_key).should be_true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns false if the signature is invalid' do
|
it 'returns false if the signature is invalid' do
|
||||||
@signable_string = "something else"
|
@signable_string = "something else"
|
||||||
|
|
||||||
@public_key = File.read(Rails.root + "spec/chubbies/chubbies.public.pem")
|
|
||||||
@controller.verify_signature(@signable_string, @sig, @public_key).should be_false
|
@controller.verify_signature(@signable_string, @sig, @public_key).should be_false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ describe AppConfig do
|
||||||
|
|
||||||
describe ".pod_uri" do
|
describe ".pod_uri" do
|
||||||
it "properly parses the pod_url" do
|
it "properly parses the pod_url" do
|
||||||
|
AppConfig.pod_uri = nil
|
||||||
|
AppConfig[:pod_url] = "http://example.org"
|
||||||
pod_uri = AppConfig[:pod_uri]
|
pod_uri = AppConfig[:pod_uri]
|
||||||
pod_uri.scheme.should == "http"
|
pod_uri.scheme.should == "http"
|
||||||
pod_uri.host.should == "example.org"
|
pod_uri.host.should == "example.org"
|
||||||
|
|
@ -152,7 +154,7 @@ describe AppConfig do
|
||||||
describe "when setting pod_url" do
|
describe "when setting pod_url" do
|
||||||
context "with a symbol" do
|
context "with a symbol" do
|
||||||
it "clears the cached pod_uri" do
|
it "clears the cached pod_uri" do
|
||||||
AppConfig[:pod_uri].host.should == "example.org"
|
AppConfig[:pod_uri].host.should_not == "joindiaspora.com"
|
||||||
AppConfig[:pod_url] = "http://joindiaspora.com"
|
AppConfig[:pod_url] = "http://joindiaspora.com"
|
||||||
AppConfig[:pod_uri].host.should == "joindiaspora.com"
|
AppConfig[:pod_uri].host.should == "joindiaspora.com"
|
||||||
end
|
end
|
||||||
|
|
@ -163,7 +165,7 @@ describe AppConfig do
|
||||||
end
|
end
|
||||||
context "with a string" do
|
context "with a string" do
|
||||||
it "clears the cached pod_uri" do
|
it "clears the cached pod_uri" do
|
||||||
AppConfig[:pod_uri].host.should == "example.org"
|
AppConfig[:pod_uri].host.should_not == "joindiaspora.com"
|
||||||
AppConfig['pod_url'] = "http://joindiaspora.com"
|
AppConfig['pod_url'] = "http://joindiaspora.com"
|
||||||
AppConfig[:pod_uri].host.should == "joindiaspora.com"
|
AppConfig[:pod_uri].host.should == "joindiaspora.com"
|
||||||
end
|
end
|
||||||
|
|
@ -174,4 +176,4 @@ describe AppConfig do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue