Class: JavaKeystore
- Inherits:
-
Object
- Object
- JavaKeystore
- Defined in:
- lib/calabash-android/java_keystore.rb
Instance Attribute Summary collapse
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#fingerprint ⇒ Object
readonly
Returns the value of attribute fingerprint.
-
#keystore_alias ⇒ Object
readonly
Returns the value of attribute keystore_alias.
-
#location ⇒ Object
readonly
Returns the value of attribute location.
-
#password ⇒ Object
readonly
Returns the value of attribute password.
-
#signature_algorithm_name ⇒ Object
readonly
Returns the value of attribute signature_algorithm_name.
Class Method Summary collapse
- .fail_if_key_missing(map, key) ⇒ Object
- .get_keystores ⇒ Object
- .keystore_from_settings ⇒ Object
- .read_keystore_with_default_password_and_alias(path) ⇒ Object
Instance Method Summary collapse
-
#initialize(location, keystore_alias, password, key_password = nil) ⇒ JavaKeystore
constructor
A new instance of JavaKeystore.
- #sign_apk(apk_path, dest_path) ⇒ Object
- #system_with_stdout_on_success(cmd, *args) ⇒ Object
Constructor Details
#initialize(location, keystore_alias, password, key_password = nil) ⇒ JavaKeystore
Returns a new instance of JavaKeystore.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/calabash-android/java_keystore.rb', line 5 def initialize(location, keystore_alias, password, key_password = nil) raise "No such keystore file '#{location}'" unless File.exists?(File.(location)) calabash_log "Reading keystore data from keystore file '#{File.(location)}'" keystore_data = system_with_stdout_on_success(Calabash::Android::Dependencies.keytool_path, '-list', '-v', '-alias', keystore_alias, '-keystore', location, '-storepass', password, '-J"-Dfile.encoding=utf-8"', '-J"-Duser.language=en-US"') if keystore_data.nil? if keystore_alias.empty? calabash_log "Could not obtain keystore data. Will try to extract alias automatically" keystore_data = system_with_stdout_on_success(Calabash::Android::Dependencies.keytool_path, '-list', '-v', '-keystore', location, '-storepass', password, '-J"-Dfile.encoding=utf-8"', '-J"-Duser.language=en-US"') aliases = keystore_data.scan(/Alias name\:\s*(.*)/).flatten if aliases.length == 0 raise 'Could not extract alias automatically. Please specify alias using calabash-android setup' elsif aliases.length > 1 raise 'Multiple aliases found in keystore. Please specify alias using calabash-android setup' else keystore_alias = aliases.first calabash_log "Extracted keystore alias '#{keystore_alias}'. Continuing" return initialize(location, keystore_alias, password) end else error = "Could not list certificates in keystore. Probably because the password was incorrect." @errors = [{:message => error}] calabash_log error raise error end end @location = location @keystore_alias = keystore_alias @password = password @key_password = key_password calabash_log "Key store data:" calabash_log keystore_data @fingerprint = extract_sha1_fingerprint(keystore_data) @signature_algorithm_name = extract_signature_algorithm_name(keystore_data) calabash_log "Fingerprint: #{fingerprint}" calabash_log "Signature algorithm name: #{signature_algorithm_name}" end |
Instance Attribute Details
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
2 3 4 |
# File 'lib/calabash-android/java_keystore.rb', line 2 def errors @errors end |
#fingerprint ⇒ Object (readonly)
Returns the value of attribute fingerprint.
2 3 4 |
# File 'lib/calabash-android/java_keystore.rb', line 2 def fingerprint @fingerprint end |
#keystore_alias ⇒ Object (readonly)
Returns the value of attribute keystore_alias.
2 3 4 |
# File 'lib/calabash-android/java_keystore.rb', line 2 def keystore_alias @keystore_alias end |
#location ⇒ Object (readonly)
Returns the value of attribute location.
2 3 4 |
# File 'lib/calabash-android/java_keystore.rb', line 2 def location @location end |
#password ⇒ Object (readonly)
Returns the value of attribute password.
2 3 4 |
# File 'lib/calabash-android/java_keystore.rb', line 2 def password @password end |
#signature_algorithm_name ⇒ Object (readonly)
Returns the value of attribute signature_algorithm_name.
3 4 5 |
# File 'lib/calabash-android/java_keystore.rb', line 3 def signature_algorithm_name @signature_algorithm_name end |
Class Method Details
.fail_if_key_missing(map, key) ⇒ Object
143 144 145 |
# File 'lib/calabash-android/java_keystore.rb', line 143 def self.fail_if_key_missing(map, key) raise "Found .calabash_settings but no #{key} defined." unless map[key] end |
.get_keystores ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/calabash-android/java_keystore.rb', line 118 def self.get_keystores if keystore = keystore_from_settings [ keystore ] else [ read_keystore_with_default_password_and_alias(File.join(ENV["HOME"], "/.android/debug.keystore")), read_keystore_with_default_password_and_alias("debug.keystore"), read_keystore_with_default_password_and_alias(File.join(ENV["HOME"], ".local/share/Xamarin/Mono\\ for\\ Android/debug.keystore")), read_keystore_with_default_password_and_alias(File.join(ENV["HOME"], "AppData/Local/Xamarin/Mono for Android/debug.keystore")), ].compact end end |
.keystore_from_settings ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/calabash-android/java_keystore.rb', line 131 def self.keystore_from_settings keystore = JSON.parse(IO.read(".calabash_settings")) if File.exist? ".calabash_settings" keystore = JSON.parse(IO.read("calabash_settings")) if File.exist? "calabash_settings" return unless keystore fail_if_key_missing(keystore, "keystore_location") fail_if_key_missing(keystore, "keystore_password") fail_if_key_missing(keystore, "keystore_alias") keystore["keystore_location"] = File.(keystore["keystore_location"]) calabash_log("Keystore location specified in #{File.exist?(".calabash_settings") ? ".calabash_settings" : "calabash_settings"}.") JavaKeystore.new(keystore["keystore_location"], keystore["keystore_alias"], keystore["keystore_password"], keystore['key_password']) end |
.read_keystore_with_default_password_and_alias(path) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/calabash-android/java_keystore.rb', line 100 def self.read_keystore_with_default_password_and_alias(path) path = File. path if File.exists? path keystore = JavaKeystore.new(path, 'androiddebugkey', 'android') if keystore.errors calabash_log "Trying to " nil else calabash_log "Unlocked keystore at #{path} - fingerprint: #{keystore.fingerprint}" keystore end else calabash_log "Trying to read keystore from: #{path} - no such file" nil end end |
Instance Method Details
#sign_apk(apk_path, dest_path) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/calabash-android/java_keystore.rb', line 48 def sign_apk(apk_path, dest_path) raise "Cannot sign with a miss configured keystore" if errors raise "No such file: #{apk_path}" unless File.exists?(apk_path) # E.g. MD5withRSA or MD5withRSAandMGF1 encryption = signature_algorithm_name.split('with')[1].split('and')[0] # keytool with newer java versions has "Signature algorithm name: SHA1withRSA (weak)" encryption.gsub!(' (weak)', '') signing_algorithm = "SHA1with#{encryption}" digest_algorithm = 'SHA1' calabash_log "Signing using the signature algorithm: '#{signing_algorithm}'" calabash_log "Signing using the digest algorithm: '#{digest_algorithm}'" cmd_args = { '-sigfile' => 'CERT', '-sigalg' => signing_algorithm, '-digestalg' => digest_algorithm, '-signedjar' => dest_path, '-storepass' => password, '-keystore' => location, } unless @key_password.nil? cmd_args['-keypass'] = @key_password end cmd_args = cmd_args.flatten cmd_args << apk_path cmd_args << keystore_alias result = system_with_stdout_on_success(Calabash::Android::Dependencies.jarsigner_path, *cmd_args) unless result raise "Could not sign app: #{apk_path}" end end |
#system_with_stdout_on_success(cmd, *args) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/calabash-android/java_keystore.rb', line 88 def system_with_stdout_on_success(cmd, *args) a = Escape.shell_command(args) cmd = "\"#{cmd}\" #{a.gsub("'", '"')}" calabash_log cmd out = `#{cmd}` if $?.exitstatus == 0 out else nil end end |