cert 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: