Skip to content

Commit

Permalink
Merge pull request #4 from christopherhein/chore/adding-ecdsa-encryption
Browse files Browse the repository at this point in the history
Adding ECDSA JWT Functions
  • Loading branch information
chriswarren committed Feb 17, 2016
2 parents c68f2d1 + 4d2ae34 commit 5463d89
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 40 deletions.
Empty file modified bin/console
100644 → 100755
Empty file.
Empty file modified bin/setup
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion doorkeeper-jwt.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

spec.add_dependency "jwt", "~> 1.4", ">= 1.4.1"
spec.add_dependency "jwt", "~> 1.5.2", ">= 1.5.2"

spec.add_development_dependency "bundler", "~> 1.8", ">= 1.8"
spec.add_development_dependency "rake", "~> 10.0", ">= 10.0"
Expand Down
84 changes: 53 additions & 31 deletions lib/doorkeeper-jwt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,66 @@

module Doorkeeper
module JWT
def self.generate(opts = {})
::JWT.encode(
token_payload(opts),
secret_key,
encryption_method
)
end
class << self
def generate(opts = {})
::JWT.encode(
token_payload(opts),
secret_key,
encryption_method
)
end

private
private

def self.token_payload(opts = {})
Doorkeeper::JWT.configuration.token_payload.call opts
end
def token_payload(opts = {})
Doorkeeper::JWT.configuration.token_payload.call opts
end

def self.secret_key
return secret_key_file if !secret_key_file.nil?
return rsa_key if rsa_encryption?
Doorkeeper::JWT.configuration.secret_key
end
def secret_key
return secret_key_file unless secret_key_file.nil?
return rsa_key if rsa_encryption?
return ecdsa_key if ecdsa_encryption?
Doorkeeper::JWT.configuration.secret_key
end

def self.secret_key_file
return nil if Doorkeeper::JWT.configuration.secret_key_path.nil?
OpenSSL::PKey::RSA.new(
File.open(Doorkeeper::JWT.configuration.secret_key_path)
)
end
def secret_key_file
return nil if Doorkeeper::JWT.configuration.secret_key_path.nil?
return rsa_key_file if rsa_encryption?
return ecdsa_key_file if ecdsa_encryption?
end

def self.encryption_method
return nil unless Doorkeeper::JWT.configuration.encryption_method
Doorkeeper::JWT.configuration.encryption_method.to_s.upcase
end
def encryption_method
return nil unless Doorkeeper::JWT.configuration.encryption_method
Doorkeeper::JWT.configuration.encryption_method.to_s.upcase
end

def self.rsa_encryption?
/RS\d{3}/ =~ encryption_method
end
def rsa_encryption?
/RS\d{3}/ =~ encryption_method
end

def self.rsa_key
OpenSSL::PKey::RSA.new(Doorkeeper::JWT.configuration.secret_key)
def ecdsa_encryption?
/ES\d{3}/ =~ encryption_method
end

def rsa_key
OpenSSL::PKey::RSA.new(Doorkeeper::JWT.configuration.secret_key)
end

def ecdsa_key
OpenSSL::PKey::EC.new(Doorkeeper::JWT.configuration.secret_key)
end

def rsa_key_file
OpenSSL::PKey::RSA.new(secret_key_file_open)
end

def ecdsa_key_file
OpenSSL::PKey::EC.new(secret_key_file_open)
end

def secret_key_file_open
File.open(Doorkeeper::JWT.configuration.secret_key_path)
end
end
end
end
64 changes: 56 additions & 8 deletions spec/doorkeeper-jwt/doorkeeper-jwt_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
end

token = Doorkeeper::JWT.generate({})
decoded_token = ::JWT.decode(token, nil, nil)
decoded_token = ::JWT.decode(token, nil, false)
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["token"]).to be_a(String)
expect(decoded_token[1]["typ"]).to eq "JWT"
Expand All @@ -28,7 +28,7 @@
end

token = Doorkeeper::JWT.generate({})
decoded_token = ::JWT.decode(token, nil, nil)
decoded_token = ::JWT.decode(token, nil, false)
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["foo"]).to eq "bar"
expect(decoded_token[1]["typ"]).to eq "JWT"
Expand All @@ -41,7 +41,7 @@
end

token = Doorkeeper::JWT.generate({})
decoded_token = ::JWT.decode(token, "super secret", nil)
decoded_token = ::JWT.decode(token, "super secret", false)
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["token"]).to be_a(String)
expect(decoded_token[1]["typ"]).to eq "JWT"
Expand All @@ -55,7 +55,8 @@
end

token = Doorkeeper::JWT.generate({})
decoded_token = ::JWT.decode(token, "super secret", "HS256")
algorithm = { algorithm: "HS256" }
decoded_token = ::JWT.decode(token, "super secret", true, algorithm)
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["token"]).to be_a(String)
expect(decoded_token[1]["typ"]).to eq "JWT"
Expand All @@ -74,7 +75,8 @@
end

token = Doorkeeper::JWT.generate({})
decoded_token = ::JWT.decode(token, "super secret", "HS256")
algorithm = { algorithm: "HS256" }
decoded_token = ::JWT.decode(token, "super secret", true, algorithm)
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["foo"]).to eq "bar"
expect(decoded_token[1]["typ"]).to eq "JWT"
Expand All @@ -93,7 +95,8 @@
end

token = Doorkeeper::JWT.generate(resource_owner_id: 1)
decoded_token = ::JWT.decode(token, "super secret", "HS256")
algorithm = { algorithm: "HS256" }
decoded_token = ::JWT.decode(token, "super secret", true, algorithm)
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["foo"]).to eq "bar_1"
expect(decoded_token[1]["typ"]).to eq "JWT"
Expand All @@ -113,7 +116,7 @@

token = Doorkeeper::JWT.generate({})
secret_key = OpenSSL::PKey::RSA.new File.read("spec/support/1024key.pem")
decoded_token = ::JWT.decode(token, secret_key, "RS512")
decoded_token = ::JWT.decode(token, secret_key, true, algorithm: "RS512")
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["foo"]).to eq "bar"
expect(decoded_token[1]["typ"]).to eq "JWT"
Expand All @@ -133,11 +136,56 @@
end

token = Doorkeeper::JWT.generate({})
decoded_token = ::JWT.decode(token, secret_key, "RS512")
decoded_token = ::JWT.decode(token, secret_key, true, algorithm: "RS512")
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["foo"]).to eq "bar"
expect(decoded_token[1]["typ"]).to eq "JWT"
expect(decoded_token[1]["alg"]).to eq "RS512"
end

it "creates a signed JWT token encrypted with an ECDSA key from a file" do
Doorkeeper::JWT.configure do
token_payload do
{
foo: "bar"
}
end
secret_key_path "spec/support/512key.pem"
encryption_method :es512
end

token = Doorkeeper::JWT.generate({})
key_file = File.read("spec/support/512key_pub.pem")
secret_key = OpenSSL::PKey::EC.new key_file
decoded_token = ::JWT.decode(token, secret_key, true, algorithm: "ES512")
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["foo"]).to eq "bar"
expect(decoded_token[1]["typ"]).to eq "JWT"
expect(decoded_token[1]["alg"]).to eq "ES512"
end

it "creates a signed JWT token encrypted with an ECDSA key from a string" do
secret_key = OpenSSL::PKey::EC.new("secp521r1")
secret_key.generate_key
public_key = OpenSSL::PKey::EC.new secret_key
public_key.private_key = nil

Doorkeeper::JWT.configure do
token_payload do
{
foo: "bar"
}
end
secret_key secret_key
encryption_method :es512
end

token = Doorkeeper::JWT.generate({})
decoded_token = ::JWT.decode(token, public_key, true, algorithm: "ES512")
expect(decoded_token[0]).to be_a(Hash)
expect(decoded_token[0]["foo"]).to eq "bar"
expect(decoded_token[1]["typ"]).to eq "JWT"
expect(decoded_token[1]["alg"]).to eq "ES512"
end
end
end
7 changes: 7 additions & 0 deletions spec/support/512key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-----BEGIN EC PRIVATE KEY-----
MIHcAgEBBEIB7L7adlDAMlMFSl2uuwyVDUTp22CZonTEkHsaBr0MYEQiPIQPhFuf
Bw4nzzkTHhlPEouhRe0wo9gzkZ+eYDuTVBugBwYFK4EEACOhgYkDgYYABADptVX+
kCmwFVo8k911+t7xigy8pvsTyhLVVSD3qT5733E85zkWoe2kc731iPmTNlRQolqd
9U9SZBFaprnpR5u0VwC+g8T6MicdQyuJmkQBVLjFmE6FTJz2bt4uJ7lG4uKWMTLq
U6KyYlXr7wJoUpgZiW9Fud0keZxGk4ns/QjoW6w6Pw==
-----END EC PRIVATE KEY-----
6 changes: 6 additions & 0 deletions spec/support/512key_pub.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA6bVV/pApsBVaPJPddfre8YoMvKb7
E8oS1VUg96k+e99xPOc5FqHtpHO99Yj5kzZUUKJanfVPUmQRWqa56UebtFcAvoPE
+jInHUMriZpEAVS4xZhOhUyc9m7eLie5RuLiljEy6lOismJV6+8CaFKYGYlvRbnd
JHmcRpOJ7P0I6FusOj8=
-----END PUBLIC KEY-----

0 comments on commit 5463d89

Please sign in to comment.