21200: copied branch from arvados-workbench2 Arvados-DCO-1.1-Signed-off-by: Lisa...
[arvados.git] / sdk / ruby-google-api-client / lib / google / api_client / auth / key_utils.rb
1 # Copyright 2010 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 module Google
16   class APIClient
17     ##
18     # Helper for loading keys from the PKCS12 files downloaded when
19     # setting up service accounts at the APIs Console.
20     #
21     module KeyUtils
22       ##
23       # Loads a key from PKCS12 file, assuming a single private key
24       # is present.
25       #
26       # @param [String] keyfile
27       #    Path of the PKCS12 file to load. If not a path to an actual file,
28       #    assumes the string is the content of the file itself.
29       # @param [String] passphrase
30       #   Passphrase for unlocking the private key
31       #
32       # @return [OpenSSL::PKey] The private key for signing assertions.
33       def self.load_from_pkcs12(keyfile, passphrase)
34         load_key(keyfile, passphrase) do |content, pass_phrase|
35           OpenSSL::PKCS12.new(content, pass_phrase).key
36         end
37       end
38
39
40       ##
41       # Loads a key from a PEM file.
42       #
43       # @param [String] keyfile
44       #    Path of the PEM file to load. If not a path to an actual file,
45       #    assumes the string is the content of the file itself.
46       # @param [String] passphrase
47       #   Passphrase for unlocking the private key
48       #
49       # @return [OpenSSL::PKey] The private key for signing assertions.
50       #
51       def self.load_from_pem(keyfile, passphrase)
52         load_key(keyfile, passphrase) do | content, pass_phrase|
53           OpenSSL::PKey::RSA.new(content, pass_phrase)
54         end
55       end
56
57       private
58
59       ##
60       # Helper for loading keys from file or memory. Accepts a block
61       # to handle the specific file format.
62       #
63       # @param [String] keyfile
64       #    Path of thefile to load. If not a path to an actual file,
65       #    assumes the string is the content of the file itself.
66       # @param [String] passphrase
67       #   Passphrase for unlocking the private key
68       #
69       # @yield [String, String]
70       #   Key file & passphrase to extract key from
71       # @yieldparam [String] keyfile
72       #   Contents of the file
73       # @yieldparam [String] passphrase
74       #   Passphrase to unlock key
75       # @yieldreturn [OpenSSL::PKey]
76       #   Private key
77       #
78       # @return [OpenSSL::PKey] The private key for signing assertions.
79       def self.load_key(keyfile, passphrase, &block)
80         begin
81           begin
82             content = File.open(keyfile, 'rb') { |io| io.read }
83           rescue
84             content = keyfile
85           end
86           block.call(content, passphrase)
87         rescue OpenSSL::OpenSSLError
88           raise ArgumentError.new("Invalid keyfile or passphrase")
89         end
90       end
91     end
92   end
93 end