Canvas Creates Private-Public Key Pair & Copy into JWK Format

Closes PLAT-3503 & PLAT-3504

Test Plan
- Verify Lti::RSAKeyPair can generate a private and a public key
- Verify the key pair can be read but not modified
- Verify the keys got copied into JWK format correctly

Change-Id: If83edebfbf631815e3078031623d6dead52017ec
Reviewed-on: https://gerrit.instructure.com/154187
Reviewed-by: Marc Alan Phillips <mphillips@instructure.com>
Tested-by: Jenkins
QA-Review: Marc Alan Phillips <mphillips@instructure.com>
Product-Review: Han Ngo <hngo@instructure.com>
This commit is contained in:
Han Ngo 2018-06-18 12:09:53 -06:00
parent b1b751a719
commit 843ec80814
4 changed files with 126 additions and 0 deletions

26
lib/lti/jwk_key_pair.rb Normal file
View File

@ -0,0 +1,26 @@
#
# Copyright (C) 2018 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
module Lti
class JWKKeyPair
attr_reader :public_key, :private_key
def to_jwk
time = Time.now.utc.iso8601
private_key.to_jwk(kid: time)
end
end
end

27
lib/lti/rsa_key_pair.rb Normal file
View File

@ -0,0 +1,27 @@
#
# Copyright (C) 2018 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require 'openssl'
module Lti
class RSAKeyPair < JWKKeyPair
def initialize(key_size: 256)
@private_key = OpenSSL::PKey::RSA.new key_size
@public_key = private_key.public_key
end
end
end

View File

@ -0,0 +1,30 @@
#
# Copyright (C) 2016 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require 'timecop'
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe Lti::JWKKeyPair do
describe "to_jwk" do
it 'has the private key in the JWK format' do
Timecop.freeze(Time.zone.now) do
keys = Lti::RSAKeyPair.new
expect(keys.to_jwk).to include(keys.private_key.to_jwk(kid: Time.now.utc.iso8601))
end
end
end
end

View File

@ -0,0 +1,43 @@
#
# Copyright (C) 2018 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe Lti::RSAKeyPair do
describe "initialize" do
it 'generates a public key of default size 256' do
keys = Lti::RSAKeyPair.new
expect(/\d+/.match(keys.public_key.to_text())[0]).to eq "256"
end
it 'generates a private key of default size 256' do
keys = Lti::RSAKeyPair.new
expect(/\d+/.match(keys.private_key.to_text())[0]).to eq "256"
end
it 'generates a public key with specified size' do
keys = Lti::RSAKeyPair.new key_size: 2048
expect(/\d+/.match(keys.public_key.to_text())[0]).to eq "2048"
end
it 'generates a private key with specified size' do
keys = Lti::RSAKeyPair.new key_size: 2048
expect(/\d+/.match(keys.private_key.to_text())[0]).to eq "2048"
end
end
end