diff --git a/.gitignore b/.gitignore index 70544e84748b14340241f3491a6ffb100bcb7ebe..3847784e1f68d90e81d04b694f65123994ec7f10 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ vendor/cache/ config/database.yml .rvmrc_custom .rvmrc.local +oidc_key.pem # Mailing list stuff config/email_offset diff --git a/app/controllers/api/openid_connect/id_tokens_controller.rb b/app/controllers/api/openid_connect/id_tokens_controller.rb index dae760892a34eb00506c33b4b5e7167cec99d740..9e8c65b89501cf272dbc46528d16a1fa8fe2566f 100644 --- a/app/controllers/api/openid_connect/id_tokens_controller.rb +++ b/app/controllers/api/openid_connect/id_tokens_controller.rb @@ -8,7 +8,7 @@ module Api private def build_jwk - JSON::JWK.new(Api::OpenidConnect::IdTokenConfig.public_key, use: :sig) + JSON::JWK.new(Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY, use: :sig) end end end diff --git a/app/models/api/openid_connect/id_token.rb b/app/models/api/openid_connect/id_token.rb index 2855a38b0aae1f94068dfcf92ce56963e70c2ff2..5acfa0ea4df410781637b76a94e1e6d0e65a75c0 100644 --- a/app/models/api/openid_connect/id_token.rb +++ b/app/models/api/openid_connect/id_token.rb @@ -12,7 +12,7 @@ module Api end def to_jwt(options={}) - to_response_object(options).to_jwt OpenidConnect::IdTokenConfig.private_key + to_response_object(options).to_jwt OpenidConnect::IdTokenConfig::PRIVATE_KEY end def to_response_object(options={}) diff --git a/features/step_definitions/auth_code_steps.rb b/features/step_definitions/auth_code_steps.rb index 36ea99cedde38e4e78cf92f73962ddce314e2d79..37b4f7b8bc6e1ef78d1e2430df4457fe8ff3f2d9 100644 --- a/features/step_definitions/auth_code_steps.rb +++ b/features/step_definitions/auth_code_steps.rb @@ -30,7 +30,7 @@ When /^I parse the tokens and use it obtain user info$/ do access_token = client_json["access_token"] encoded_id_token = client_json["id_token"] decoded_token = OpenIDConnect::ResponseObject::IdToken.decode encoded_id_token, - Api::OpenidConnect::IdTokenConfig.public_key + Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY expect(decoded_token.sub).to eq(@me.diaspora_handle) get api_openid_connect_user_info_path, access_token: access_token end diff --git a/lib/api/openid_connect/id_token_config.rb b/lib/api/openid_connect/id_token_config.rb index d046d4b7a28dfda369bcdfd5004e9f30c4c7cc94..541fa466352368c85c91bd6c494dd8341bb0866a 100644 --- a/lib/api/openid_connect/id_token_config.rb +++ b/lib/api/openid_connect/id_token_config.rb @@ -1,13 +1,18 @@ module Api module OpenidConnect class IdTokenConfig - @@key = OpenSSL::PKey::RSA.new(2048) - def self.public_key - @@key.public_key - end - def self.private_key - @@key + private_key = OpenSSL::PKey::RSA.new(2048) + key_file_path = File.join(Rails.root, "config", "oidc_key.pem") + if File.exist?(key_file_path) + private_key = OpenSSL::PKey::RSA.new(File.read(key_file_path)) + else + open key_file_path, "w" do |io| + io.write private_key.to_pem + end + File.chmod(0600, key_file_path) end + PRIVATE_KEY = private_key + PUBLIC_KEY = private_key.public_key end end end diff --git a/spec/controllers/api/openid_connect/authorizations_controller_spec.rb b/spec/controllers/api/openid_connect/authorizations_controller_spec.rb index 244799a284b7b3037998429ba3e24332d1befb77..5233ef9762b798b9aafa10b5df6bf22d30437b20 100644 --- a/spec/controllers/api/openid_connect/authorizations_controller_spec.rb +++ b/spec/controllers/api/openid_connect/authorizations_controller_spec.rb @@ -146,7 +146,7 @@ describe Api::OpenidConnect::AuthorizationsController, type: :controller do expect(response.location).to have_content("id_token=") encoded_id_token = response.location[/(?<=id_token=)[^&]+/] decoded_token = OpenIDConnect::ResponseObject::IdToken.decode encoded_id_token, - Api::OpenidConnect::IdTokenConfig.public_key + Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY expect(decoded_token.nonce).to eq("4130930983") expect(decoded_token.exp).to be > Time.zone.now.utc.to_i end @@ -164,7 +164,7 @@ describe Api::OpenidConnect::AuthorizationsController, type: :controller do expect(response.location).to have_content("id_token=") encoded_id_token = response.location[/(?<=id_token=)[^&]+/] decoded_token = OpenIDConnect::ResponseObject::IdToken.decode encoded_id_token, - Api::OpenidConnect::IdTokenConfig.public_key + Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY expect(decoded_token.nonce).to eq("4130930983") expect(decoded_token.exp).to be > Time.zone.now.utc.to_i end @@ -196,7 +196,7 @@ describe Api::OpenidConnect::AuthorizationsController, type: :controller do it "should return the id token in a fragment" do encoded_id_token = response.location[/(?<=id_token=)[^&]+/] decoded_token = OpenIDConnect::ResponseObject::IdToken.decode encoded_id_token, - Api::OpenidConnect::IdTokenConfig.public_key + Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY expect(decoded_token.nonce).to eq("4180930983") expect(decoded_token.exp).to be > Time.zone.now.utc.to_i end @@ -204,7 +204,7 @@ describe Api::OpenidConnect::AuthorizationsController, type: :controller do it "should return a valid access token in a fragment" do encoded_id_token = response.location[/(?<=id_token=)[^&]+/] decoded_token = OpenIDConnect::ResponseObject::IdToken.decode encoded_id_token, - Api::OpenidConnect::IdTokenConfig.public_key + Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY access_token = response.location[/(?<=access_token=)[^&]+/] access_token_check_num = UrlSafeBase64.encode64(OpenSSL::Digest::SHA256.digest(access_token)[0, 128 / 8]) expect(decoded_token.at_hash).to eq(access_token_check_num) @@ -227,7 +227,7 @@ describe Api::OpenidConnect::AuthorizationsController, type: :controller do expect(response.location).to have_content("id_token=") encoded_id_token = response.location[/(?<=id_token=)[^&]+/] decoded_token = OpenIDConnect::ResponseObject::IdToken.decode encoded_id_token, - Api::OpenidConnect::IdTokenConfig.public_key + Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY expect(decoded_token.nonce).to eq("4180930983") expect(decoded_token.exp).to be > Time.zone.now.utc.to_i end diff --git a/spec/controllers/api/openid_connect/id_tokens_controller_spec.rb b/spec/controllers/api/openid_connect/id_tokens_controller_spec.rb index 06930c45b3d3154233a788ab3f9e966f0dcd062d..6827863d5316dc39a1308f3f4d7a642b044eeda9 100644 --- a/spec/controllers/api/openid_connect/id_tokens_controller_spec.rb +++ b/spec/controllers/api/openid_connect/id_tokens_controller_spec.rb @@ -13,7 +13,7 @@ describe Api::OpenidConnect::IdTokensController, type: :controller do JSON::JWK.decode jwk end public_key = public_keys.first - expect(Api::OpenidConnect::IdTokenConfig.private_key.public_key.to_s).to eq(public_key.to_s) + expect(Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY.to_s).to eq(public_key.to_s) end end end diff --git a/spec/lib/api/openid_connect/token_endpoint_spec.rb b/spec/lib/api/openid_connect/token_endpoint_spec.rb index 1dad2c13368d0c64fa8edab85722a681d7c5b5e9..dfbee1eebb1da6140c1646425492594be0c74913 100644 --- a/spec/lib/api/openid_connect/token_endpoint_spec.rb +++ b/spec/lib/api/openid_connect/token_endpoint_spec.rb @@ -21,7 +21,7 @@ describe Api::OpenidConnect::TokenEndpoint, type: :request do json = JSON.parse(response.body) encoded_id_token = json["id_token"] decoded_token = OpenIDConnect::ResponseObject::IdToken.decode encoded_id_token, - Api::OpenidConnect::IdTokenConfig.public_key + Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY expected_guid = bob.pairwise_pseudonymous_identifiers.find_by(sector_identifier: "https://example.com/uri").guid expect(decoded_token.sub).to eq(expected_guid) expect(decoded_token.exp).to be > Time.zone.now.utc.to_i @@ -31,7 +31,7 @@ describe Api::OpenidConnect::TokenEndpoint, type: :request do json = JSON.parse(response.body) encoded_id_token = json["id_token"] decoded_token = OpenIDConnect::ResponseObject::IdToken.decode encoded_id_token, - Api::OpenidConnect::IdTokenConfig.public_key + Api::OpenidConnect::IdTokenConfig::PUBLIC_KEY access_token = json["access_token"] access_token_check_num = UrlSafeBase64.encode64(OpenSSL::Digest::SHA256.digest(access_token)[0, 128 / 8]) expect(decoded_token.at_hash).to eq(access_token_check_num)