cert 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6144b46854a7c5b8125135062907eca353cef490
4
+ data.tar.gz: d107c1c5f6ad757c4b8cbf3340cdd306a34a6fe4
5
+ SHA512:
6
+ metadata.gz: c084c2f0985bae99f5c43d79a3ac4388262351a13843f34472461658e884f92c401c36b25d5ee60670696cb594432a2bd7abcc28e459432cb3f8a9108ebde5c9
7
+ data.tar.gz: 7698d2b47357a8c504f2e10e579f92ad3ad532b258d805befc99a0efa82fb61655eedd275f6629d8e4eeed7db5c24715c8b7ced9d16b4ed100870dc5780d9db1
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Felix Krause
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,156 @@
1
+ <h3 align="center">
2
+ <a href="https://github.com/KrauseFx/fastlane">
3
+ <img src="assets/fastlane.png" width="150" />
4
+ <br />
5
+ fastlane
6
+ </a>
7
+ </h3>
8
+ <p align="center">
9
+ <a href="https://github.com/KrauseFx/deliver">deliver</a> &bull;
10
+ <a href="https://github.com/KrauseFx/snapshot">snapshot</a> &bull;
11
+ <a href="https://github.com/KrauseFx/frameit">frameit</a> &bull;
12
+ <a href="https://github.com/KrauseFx/pem">PEM</a> &bull;
13
+ <a href="https://github.com/KrauseFx/sigh">sigh</a> &bull;
14
+ <a href="https://github.com/KrauseFx/produce">produce</a> &bull;
15
+ <b>cert</b>
16
+ </p>
17
+ -------
18
+
19
+ <p align="center">
20
+ <img src="assets/cert.png">
21
+ </p>
22
+
23
+ cert - Create new iOS signing certificates
24
+ ============
25
+
26
+ [![Twitter: @KauseFx](https://img.shields.io/badge/contact-@KrauseFx-blue.svg?style=flat)](https://twitter.com/KrauseFx)
27
+ [![License](http://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/KrauseFx/cert/blob/master/LICENSE)
28
+ [![Gem](https://img.shields.io/gem/v/cert.svg?style=flat)](http://rubygems.org/gems/cert)
29
+
30
+ ###### Automatically create and maintain iOS code signing certificates.
31
+
32
+ ##### This tool was sponsored by [AppInstitute](http://appinstitute.co.uk/).
33
+
34
+ Get in contact with the developer on Twitter: [@KrauseFx](https://twitter.com/KrauseFx)
35
+
36
+ -------
37
+ <p align="center">
38
+ <a href="#installation">Installation</a> &bull;
39
+ <a href="#why">Why?</a> &bull;
40
+ <a href="#usage">Usage</a> &bull;
41
+ <a href="#how-does-it-work">How does it work?</a> &bull;
42
+ <a href="#tips">Tips</a> &bull;
43
+ <a href="#need-help">Need help?</a>
44
+ </p>
45
+
46
+ -------
47
+
48
+ <h5 align="center"><code>cert</code> is part of <a href="http://fastlane.tools">fastlane</a>: connect all deployment tools into one streamlined workflow.</h5>
49
+
50
+
51
+
52
+ # Installation
53
+ sudo gem install cert
54
+
55
+ Make sure, you have the latest version of the Xcode command line tools installed:
56
+
57
+ xcode-select --install
58
+
59
+ # Why?
60
+
61
+ Please check out [this guide](https://github.com/KrauseFx/cert/blob/master/ManualSteps.md) to get started with a signing certificate and a provisioning profile.
62
+
63
+ **After** checking out the [guide](https://github.com/KrauseFx/cert/blob/master/ManualSteps.md), take a look at this lovely gif:
64
+
65
+ ![assets/cert.gif](assets/cert.gif)
66
+
67
+ In the gif I used `cert && sigh`, which will first create an iOS code signing certificate and then a provisioning profile for your app if `cert` succeeded.
68
+
69
+ # Usage
70
+
71
+ cert
72
+
73
+ This will check if any of the available signing certificates is installed.
74
+
75
+ Only if a new certificate needs to be created, `cert` will
76
+
77
+ - Create a new private key
78
+ - Create a new signing request
79
+ - Generate, downloads and installs the certificate
80
+ - Import all the generated files into your Keychain
81
+
82
+
83
+ ```cert``` will never revoke your existing certificates. If you can't create any more certificates, `cert` will raise an exception, which means, you have to revoke one of the existing certificates to make room for a new one.
84
+
85
+
86
+ You can pass your Apple ID:
87
+
88
+ cert -u cert@krausefx.com
89
+
90
+
91
+ ## Environment Variables
92
+ In case you prefer environment variables:
93
+
94
+ - ```CERT_USERNAME```
95
+ - ```CERT_TEAM_ID```
96
+ - ```CERT_KEYCHAIN_PATH``` The path to a specific Keychain if you don't want to use the default one
97
+
98
+ ## Use with [`sigh`](https://github.com/KrauseFx/sigh)
99
+
100
+ `cert` is becomes really interesting when it's used in [`fastlane`](https://github.com/KrauseFx/fastlane) in combination with [`sigh`](https://github.com/KrauseFx/sigh).
101
+
102
+ Update your `Fastfile` to contain the following code:
103
+
104
+ ```ruby
105
+ lane :beta do
106
+ cert
107
+ sigh :force
108
+ end
109
+ ```
110
+
111
+ `:force` will make sure to re-generate the provisioning profile on each run.
112
+ This will result in `sigh` always using the correct signing certificate, which is installed on the local machine.
113
+
114
+
115
+ # How does it work?
116
+
117
+ - `cert` accesses the ```iOS Dev Center``` to create or download your certificate. See: [developer_center.rb](https://github.com/KrauseFx/cert/blob/master/lib/cert/developer_center.rb).
118
+ - The ```.certSigningRequest``` file will be generated in [signing_request.rb](https://github.com/KrauseFx/cert/blob/master/lib/cert/signing_request.rb)
119
+
120
+
121
+ ## How is my password stored?
122
+ ```cert``` uses the [password manager](https://github.com/KrauseFx/CredentialsManager) from `fastlane`. Take a look the [CredentialsManager README](https://github.com/KrauseFx/CredentialsManager) for more information.
123
+
124
+ # Tips
125
+
126
+ ## [`fastlane`](http://fastlane.tools) Toolchain
127
+
128
+ - [`fastlane`](http://fastlane.tools): Connect all deployment tools into one streamlined workflow
129
+ - [`deliver`](https://github.com/KrauseFx/deliver): Upload screenshots, metadata and your app to the App Store using a single command
130
+ - [`snapshot`](https://github.com/KrauseFx/snapshot): Automate taking localized screenshots of your iOS app on every device
131
+ - [`frameit`](https://github.com/KrauseFx/frameit): Quickly put your screenshots into the right device frames
132
+ - [`PEM`](https://github.com/KrauseFx/pem): Automatically generate and renew your push notification profiles
133
+ - [`sigh`](https://github.com/KrauseFx/sigh): Because you would rather spend your time building stuff than fighting provisioning
134
+ - [`produce`](https://github.com/KrauseFx/produce): Create new iOS apps on iTunes Connect and Dev Portal using the command line
135
+
136
+ ## Use the 'Provisioning Quicklook plugin'
137
+ Download and install the [Provisioning Plugin](https://github.com/chockenberry/Provisioning).
138
+
139
+ ![assets/QuickLookScreenshot.png](assets/QuickLookScreenshot.png)
140
+
141
+
142
+ # Need help?
143
+ - If there is a technical problem with ```cert```, submit an issue.
144
+ - I'm available for contract work - drop me an email: cert@krausefx.com
145
+
146
+ # License
147
+ This project is licensed under the terms of the MIT license. See the LICENSE file.
148
+
149
+ # Contributing
150
+
151
+ 1. Create an issue to discuss about your idea
152
+ 2. Fork it (https://github.com/KrauseFx/cert/fork)
153
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
154
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
155
+ 5. Push to the branch (`git push origin my-new-feature`)
156
+ 6. Create a new Pull Request
data/bin/cert ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push File.expand_path("../../lib", __FILE__)
4
+
5
+ require 'cert'
6
+ require 'commander'
7
+ require 'credentials_manager/password_manager'
8
+ require 'credentials_manager/appfile_config'
9
+
10
+ HighLine.track_eof = false
11
+
12
+ class CertApplication
13
+ include Commander::Methods
14
+
15
+ def run
16
+ program :version, Cert::VERSION
17
+ program :description, 'CLI for \'cert\' - Create new iOS code signing certificates'
18
+ program :help, 'Author', 'Felix Krause <cert@krausefx.com>'
19
+ program :help, 'Website', 'http://fastlane.tools'
20
+ program :help, 'GitHub', 'https://github.com/krausefx/cert'
21
+ program :help_formatter, :compact
22
+
23
+ always_trace!
24
+
25
+ global_option '-u', '--username STRING', 'Your Apple ID username'
26
+
27
+ command :create do |c|
28
+ c.syntax = 'cert create'
29
+ c.description = 'Create new iOS code signing certificates'
30
+
31
+ c.action do |args, options|
32
+ username(options)
33
+
34
+ Cert::CertRunner.run
35
+
36
+ installed = Cert::CertChecker.is_installed?ENV["CER_FILE_PATH"]
37
+ raise "Could not find the newly generated certificate installed" unless installed
38
+ end
39
+ end
40
+
41
+ def username(options)
42
+ user = options.username
43
+ user ||= ENV["CERT_USERNAME"]
44
+ user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
45
+
46
+ CredentialsManager::PasswordManager.shared_manager(user) if user
47
+ end
48
+
49
+ default_command :create
50
+
51
+ run!
52
+ end
53
+ end
54
+
55
+ CertApplication.new.run
@@ -0,0 +1,30 @@
1
+ module Cert
2
+ # This class checks if a specific certificate is installed on the current mac
3
+ class CertChecker
4
+ def self.is_installed?(path)
5
+ raise "Could not find file '#{path}'".red unless File.exists?(path)
6
+
7
+ ids = installed_identies
8
+ finger_print = sha1_fingerprint(path)
9
+
10
+ return ids.include?finger_print
11
+ end
12
+
13
+ def self.installed_identies
14
+ available = `security find-identity -v -p codesigning`
15
+ ids = []
16
+ available.split("\n").each do |current|
17
+ (ids << current.match(/.*\) (.*) \".*/)[1]) rescue nil # the last line does not match
18
+ end
19
+
20
+ return ids
21
+ end
22
+
23
+ def self.sha1_fingerprint(path)
24
+ result = `openssl x509 -in "#{path}" -inform der -noout -sha1 -fingerprint`
25
+ result = result.match(/SHA1 Fingerprint=(.*)/)[1]
26
+ result.gsub!(":", "")
27
+ return result
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,7 @@
1
+ module Cert
2
+ class CertRunner
3
+ def self.run
4
+ FastlaneCore::DeveloperCenter.new.run
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ module Cert
2
+ class DependencyChecker
3
+ def self.check_dependencies
4
+ self.check_xcode_select
5
+ end
6
+
7
+ def self.check_xcode_select
8
+ unless `xcode-select -v`.include?"xcode-select version "
9
+ Helper.log.fatal '#############################################################'
10
+ Helper.log.fatal "# You have to install the Xcode commdand line tools to use cert"
11
+ Helper.log.fatal "# Install the latest version of Xcode from the AppStore"
12
+ Helper.log.fatal "# Run xcode-select --install to install the developer tools"
13
+ Helper.log.fatal '#############################################################'
14
+ raise "Run 'xcode-select --install' and start cert again"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,174 @@
1
+ require 'fastlane_core/developer_center/developer_center'
2
+
3
+ module FastlaneCore
4
+ class DeveloperCenter
5
+ CERTS_URL = "https://developer.apple.com/account/ios/certificate/certificateList.action"
6
+ CREATE_CERT_URL = "https://developer.apple.com/account/ios/certificate/certificateCreate.action"
7
+
8
+ # This will check if there is at least one of the certificates already installed on the local machine
9
+ # This will store the resulting file name in ENV 'CER_FILE_PATH' and the Cert ID in 'CER_CERTIFICATE_ID'
10
+ def run
11
+ file = find_existing_cert
12
+ if file
13
+ # We don't need to do anything :)
14
+ ENV["CER_FILE_PATH"] = file
15
+ else
16
+ create_certificate
17
+ end
18
+ rescue => ex
19
+ error_occured(ex)
20
+ end
21
+
22
+ def find_existing_cert
23
+ visit "#{CERTS_URL}?type=distribution"
24
+
25
+ # Download all available certs to check if they are installed using the SHA1 hash
26
+ certs = code_signing_certificate
27
+ certs.each do |current|
28
+ display_id = current['certificateId']
29
+ type_id = current['certificateTypeDisplayId']
30
+ url = "/account/ios/certificate/certificateContentDownload.action?displayId=#{display_id}&type=#{type_id}"
31
+
32
+ output = File.join(TMP_FOLDER, "#{display_id}-#{type_id}.cer")
33
+ download_url(url, output)
34
+ if Cert::CertChecker.is_installed?output
35
+ # We'll use this one, since it's installed on the local machine
36
+ ENV["CER_CERTIFICATE_ID"] = display_id
37
+ Helper.log.info "Found the certificate #{display_id}-#{type_id} which is installed on the local machine. Using this one.".green
38
+ return output
39
+ end
40
+ end
41
+
42
+ Helper.log.info "Couldn't find an existing certificate... creating a new one"
43
+ return false
44
+ rescue => ex
45
+ error_occured(ex)
46
+ end
47
+
48
+ # This will actually create a new certificate
49
+ def create_certificate
50
+ visit CREATE_CERT_URL
51
+ wait_for_elements("form[name='certificateSave']")
52
+
53
+ Helper.log.info "Creating a new code signing certificate"
54
+
55
+ # select certificate type
56
+ app_store_toggle = first("input#type-iosNoOCSP")
57
+ if !!app_store_toggle['disabled']
58
+ # Limit of certificates already reached
59
+ raise "Could not create another certificate, reached the maximum number of available certificates.".red
60
+ end
61
+
62
+ app_store_toggle.click
63
+
64
+ click_next # submit the certificate type
65
+ sleep 2
66
+ click_next # information about how to upload the file (no action required on this step)
67
+
68
+ cert_signing_request = Cert::SigningRequest.get_path
69
+ Helper.log.info "Uploading the cert signing request '#{cert_signing_request}'"
70
+
71
+
72
+ wait_for_elements("input[name='upload']").first.set cert_signing_request # upload the cert signing request
73
+ sleep 1
74
+ click_next
75
+
76
+ sleep 3
77
+
78
+ while all(:css, '.loadingMessage').count > 0
79
+ Helper.log.debug "Waiting for iTC to generate the profile"
80
+ sleep 2
81
+ end
82
+
83
+ Helper.log.info "Downloading newly generated certificate"
84
+ sleep 2
85
+
86
+ # Now download the certificate
87
+ download_button = wait_for_elements(".button.small.blue").first
88
+ url = download_button['href']
89
+
90
+ path = File.join(TMP_FOLDER, "certificate.cer")
91
+ download_url(url, path)
92
+
93
+ certificate_id = url.match(/.*displayId=(.*)&type.*/)[1]
94
+
95
+ ENV["CER_FILE_PATH"] = path
96
+ ENV["CER_CERTIFICATE_ID"] = certificate_id
97
+ Helper.log.info "Successfully downloaded latest .cer file to '#{path}' (#{certificate_id})".green
98
+
99
+ Cert::KeychainImporter::import_file(path)
100
+ rescue => ex
101
+ error_occured(ex)
102
+ end
103
+
104
+
105
+ private
106
+ def download_url(url, output_path)
107
+ host = Capybara.current_session.current_host
108
+ url = [host, url].join('')
109
+ Helper.log.info "Downloading URL: '#{url}'"
110
+
111
+ cookieString = ""
112
+ page.driver.cookies.each do |key, cookie|
113
+ cookieString << "#{cookie.name}=#{cookie.value};" # append all known cookies
114
+ end
115
+ data = open(url, {'Cookie' => cookieString}).read
116
+
117
+ raise "Something went wrong when downloading the certificate" unless data
118
+
119
+ dataWritten = File.write(output_path, data)
120
+
121
+ if dataWritten == 0
122
+ raise "Can't write to #{output_path}"
123
+ end
124
+ end
125
+
126
+ # Returns a hash, that contains information about the iOS certificate
127
+ # @example
128
+ # {"certRequestId"=>"B23Q2P396B",
129
+ # "name"=>"SunApps GmbH",
130
+ # "statusString"=>"Issued",
131
+ # "expirationDate"=>"2015-11-25T22:45:50Z",
132
+ # "expirationDateString"=>"Nov 25, 2015",
133
+ # "ownerType"=>"team",
134
+ # "ownerName"=>"SunApps GmbH",
135
+ # "ownerId"=>"....",
136
+ # "canDownload"=>true,
137
+ # "canRevoke"=>true,
138
+ # "certificateId"=>"....",
139
+ # "certificateStatusCode"=>0,
140
+ # "certRequestStatusCode"=>4,
141
+ # "certificateTypeDisplayId"=>"...",
142
+ # "serialNum"=>"....",
143
+ # "typeString"=>"iOS Distribution"},
144
+ def code_signing_certificate
145
+ certs_url = "https://developer.apple.com/account/ios/certificate/certificateList.action?type=distribution"
146
+ visit certs_url
147
+
148
+ certificateDataURL = wait_for_variable('certificateDataURL')
149
+ certificateRequestTypes = wait_for_variable('certificateRequestTypes')
150
+ certificateStatuses = wait_for_variable('certificateStatuses')
151
+
152
+ url = [certificateDataURL, certificateRequestTypes, certificateStatuses].join('')
153
+
154
+ # https://developer.apple.com/services-account/.../account/ios/certificate/listCertRequests.action?content-type=application/x-www-form-urlencoded&accept=application/json&requestId=...&userLocale=en_US&teamId=...&types=...&status=4&certificateStatus=0&type=distribution
155
+
156
+ available = []
157
+
158
+ certs = post_ajax(url)['certRequests']
159
+ certs.each do |current_cert|
160
+ if current_cert['typeString'] == 'iOS Distribution'
161
+ # The other profiles are push profiles
162
+ # We only care about the distribution profile
163
+ available << current_cert # mostly we only care about the 'certificateId'
164
+ end
165
+ end
166
+
167
+ return available
168
+ end
169
+
170
+ def click_next
171
+ wait_for_elements('.button.small.blue.right.submit').last.click
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,10 @@
1
+ module Cert
2
+ class KeychainImporter
3
+ def self.import_file(path)
4
+ raise "Could not find file '#{path}'".red unless File.exists?(path)
5
+ keychain = ENV["CERT_KEYCHAIN_PATH"] || "#{Dir.home}/Library/Keychains/login.keychain"
6
+
7
+ puts `security import '#{path}' -k '#{keychain}'`
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,33 @@
1
+ module Cert
2
+ class SigningRequest
3
+ def self.get_path
4
+ self.generate
5
+ end
6
+
7
+ def self.generate
8
+ Helper.log.info "Creating a signing certificate for you.".green
9
+ key = OpenSSL::PKey::RSA.new 2048
10
+
11
+ # Generate CSR
12
+ csr = OpenSSL::X509::Request.new
13
+ csr.version = 0
14
+ csr.subject = OpenSSL::X509::Name.new([
15
+ ['CN', "PEM", OpenSSL::ASN1::UTF8STRING]
16
+ ])
17
+ csr.public_key = key.public_key
18
+ csr.sign key, OpenSSL::Digest::SHA1.new
19
+
20
+ path = File.join(TMP_FOLDER, 'CertCertificateSigningRequest.certSigningRequest')
21
+ private_key_path = File.join(TMP_FOLDER, 'private_key.p12')
22
+ File.write(path, csr.to_pem)
23
+ File.write(private_key_path, key)
24
+
25
+ # Import the private key into the Keychain
26
+ puts `chmod 600 '#{private_key_path}'` # otherwise we're not allowed to import the private key
27
+ KeychainImporter::import_file(private_key_path)
28
+
29
+ Helper.log.info "Successfully generated .certSigningRequest at path '#{path}'".green
30
+ return path
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module Cert
2
+ VERSION = "0.1.0"
3
+ end
data/lib/cert.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'cert/version'
2
+ require 'cert/dependency_checker'
3
+ require 'cert/developer_center'
4
+ require 'cert/cert_runner'
5
+ require 'cert/cert_checker'
6
+ require 'cert/signing_request'
7
+ require 'cert/keychain_importer'
8
+
9
+ require 'fastlane_core'
10
+
11
+ module Cert
12
+ TMP_FOLDER = "/tmp/cert/"
13
+ FileUtils.mkdir_p TMP_FOLDER
14
+
15
+ Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
16
+
17
+ ENV['FASTLANE_TEAM_ID'] ||= ENV["CERT_TEAM_ID"]
18
+
19
+ FastlaneCore::UpdateChecker.verify_latest_version('cert', Cert::VERSION)
20
+ DependencyChecker.check_dependencies
21
+ end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cert
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Felix Krause
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fastlane_core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 3.1.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 3.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 0.8.7.4
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 0.8.7.4
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 1.19.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.19.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: codeclimate-test-reporter
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: Create new iOS code signing certificates
126
+ email:
127
+ - cert@krausefx.com
128
+ executables:
129
+ - cert
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - LICENSE
134
+ - README.md
135
+ - bin/cert
136
+ - lib/cert.rb
137
+ - lib/cert/cert_checker.rb
138
+ - lib/cert/cert_runner.rb
139
+ - lib/cert/dependency_checker.rb
140
+ - lib/cert/developer_center.rb
141
+ - lib/cert/keychain_importer.rb
142
+ - lib/cert/signing_request.rb
143
+ - lib/cert/version.rb
144
+ homepage: http://fastlane.tools
145
+ licenses:
146
+ - MIT
147
+ metadata: {}
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - '>='
155
+ - !ruby/object:Gem::Version
156
+ version: 2.0.0
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - '>='
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ requirements: []
163
+ rubyforge_project:
164
+ rubygems_version: 2.2.2
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: Create new iOS code signing certificates
168
+ test_files: []
169
+ has_rdoc: