rubygems-openpgp 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.asc +11 -0
- data/LICENSE +31 -0
- data/README.md +262 -0
- data/lib/rubygems/commands/sbuild_command.rb +33 -0
- data/lib/rubygems/commands/sign_command.rb +71 -0
- data/lib/rubygems/commands/verify_command.rb +59 -0
- data/lib/rubygems/commands/vinstall_command.rb +33 -0
- data/lib/rubygems/gem_openpgp.rb +60 -0
- data/lib/rubygems_plugin.rb +6 -0
- metadata +56 -0
- metadata.gz.asc +11 -0
data.tar.gz.asc
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
-----BEGIN PGP SIGNATURE-----
|
2
|
+
Version: GnuPG v1.4.10 (GNU/Linux)
|
3
|
+
|
4
|
+
iQEcBAABAwAGBQJN4YzUAAoJEP5F5V2hilTWY/oH/3fdEbnj5IvbnX4TsLgTnhak
|
5
|
+
tQuVDRfHG3LU62m2dPWnhnC10/pxVgnJYn4g2ldzIo9A9tgg9rx1UzH1lRNp29ky
|
6
|
+
l8LaRkv2QJrniRFtOmihkQFOYw7dCcK8Pm5MzHVh/s6cKD6q2pRcrJnj88vFNrDz
|
7
|
+
gR3dSWzqjdH5heSUJqfebc+dEOZZWBy6OFjPFtgn5TZJVpud8Vl4PlvjpHc63frN
|
8
|
+
9K1oRe7h+DrFuVb3OBsWyddsjMhYya05yIah2kcwYQuzXycv1kun9VZYxLJlPj9z
|
9
|
+
X6bKnEnqCiHsqLCEG/fQsj5FJDiDJZYyFR+JHMFmDScFVJrLcU6rqyG3aCn7g/w=
|
10
|
+
=7S+s
|
11
|
+
-----END PGP SIGNATURE-----
|
data/LICENSE
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
Copyright (c) 2011, Grant T. Olson
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are
|
6
|
+
met:
|
7
|
+
|
8
|
+
* Redistributions of source code must retain the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
* Redistributions in binary form must reproduce the above
|
12
|
+
copyright notice, this list of conditions and the following
|
13
|
+
disclaimer in the documentation and/or other materials provided
|
14
|
+
with the distribution.
|
15
|
+
|
16
|
+
* Neither the name of the Grant T. Olson nor the names of
|
17
|
+
additional contributors may be used to endorse or promote
|
18
|
+
products derived from this software without specific prior
|
19
|
+
written permission.
|
20
|
+
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
22
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
23
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
24
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
25
|
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
26
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
27
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
28
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
29
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
30
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
31
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,262 @@
|
|
1
|
+
rubygems-openpgp
|
2
|
+
================
|
3
|
+
|
4
|
+
This gem allows cryptographic signing of ruby gems with OpenPGP
|
5
|
+
instead of the current method involving OpenSSL. I think OpenPGP is a
|
6
|
+
much better choice than X509 certificates for verifying open source
|
7
|
+
components.
|
8
|
+
|
9
|
+
My proposal as to why we should do so, and how to add certification
|
10
|
+
infrastructure into place, follows. Note this project doesn't attempt
|
11
|
+
to address the issue of creating a ruby gem Signing Authority.
|
12
|
+
|
13
|
+
Prerequisites
|
14
|
+
-------------
|
15
|
+
|
16
|
+
A working installation of gpg.
|
17
|
+
|
18
|
+
An openpgp private key.
|
19
|
+
|
20
|
+
Getting Started with gpg
|
21
|
+
------------------------
|
22
|
+
|
23
|
+
If you're unfamiliar with gpg, please read the [GNU Privacy
|
24
|
+
Handbook](http://www.gnupg.org/gph/en/manual.html) . If you're too
|
25
|
+
lazy or impatient to do so, you can get started quickly by:
|
26
|
+
|
27
|
+
1. Installing the appropriate gpg package for your OS if you don't
|
28
|
+
already have one.
|
29
|
+
|
30
|
+
1. Running `gpg --gen-key` to create your key.
|
31
|
+
|
32
|
+
If you use this key for anything more than a few local tests, please:
|
33
|
+
|
34
|
+
1. Publish your public key so others can retrieve it.
|
35
|
+
`gpg --keyserver pool.sks-keyservers.net --send-keys <your-new-key-id>`
|
36
|
+
|
37
|
+
1. Backup your private key. It's irretrievable if lost or corrupted.
|
38
|
+
|
39
|
+
1. Generate a revocation certificate. This allows you to invalidate a
|
40
|
+
key if a malicious user gains access.
|
41
|
+
|
42
|
+
1. Read the GNU Privacy Handbook above.
|
43
|
+
|
44
|
+
Signing example
|
45
|
+
---------------
|
46
|
+
|
47
|
+
gem build openpgp_signed_hola.gemspec
|
48
|
+
gem sign openpgp_signed_hola-0.0.0.gemspec
|
49
|
+
gem push opnepgp_signed_hola-0.0.0.gemspec
|
50
|
+
|
51
|
+
Verification Example
|
52
|
+
--------------------
|
53
|
+
|
54
|
+
A test gem **openpgp_signed_hola** is on rubygems.org. To try out
|
55
|
+
this extension:
|
56
|
+
|
57
|
+
gem fetch openpgp_signed_hola
|
58
|
+
gem verify openpgp_signed_hola-0.0.0.gem
|
59
|
+
gem install openpgp_signed_hola-0.0.0.gem
|
60
|
+
|
61
|
+
But That Just Failed!
|
62
|
+
---------------------
|
63
|
+
|
64
|
+
The first time you do this, the `gem verify` command will probably
|
65
|
+
fail. This is because you don't have my public key. To automatically
|
66
|
+
retrieve the key from the keyservers, run:
|
67
|
+
|
68
|
+
gem verify --get-key openpgp_signed_hola-0.0.0.gem
|
69
|
+
|
70
|
+
The key will be automatically downloaded, and verification should now
|
71
|
+
succeed.
|
72
|
+
|
73
|
+
There are security implications here. You've downloaded the key based
|
74
|
+
on the information contained in the gem itself. If a malicious user
|
75
|
+
has tampered with the gem, they could easily provide a forged OpenPGP
|
76
|
+
key as well. This is why your output includes the following warning:
|
77
|
+
|
78
|
+
gpg: WARNING: This key is not certified with a trusted signature!
|
79
|
+
gpg: There is no indication that the signature belongs to the owner.
|
80
|
+
|
81
|
+
You still don't know if this key *really* belongs to me. If possible,
|
82
|
+
you should verify the key signature through an out-band-channel. This
|
83
|
+
may be the project page, a release email from the author, or some
|
84
|
+
other means.
|
85
|
+
|
86
|
+
For example, you can obtain the fingerprint on my key from [my
|
87
|
+
personal website](http://www.grant-olson.net/openpgp-key).
|
88
|
+
|
89
|
+
I've also included it right here in the README hosted on github:
|
90
|
+
|
91
|
+
pub 2048R/E3B5806F 2010-01-11 [expires: 2012-01-04]
|
92
|
+
Key fingerprint = A530 C31C D762 0D26 E2BA C384 B6F6 FFD0 E3B5 806F
|
93
|
+
uid Grant T. Olson (Personal email) <kgo@grant-olson.net>
|
94
|
+
uid Grant T. Olson (pikimal) <grant@pikimal.com>
|
95
|
+
sub 2048R/6A8F7CF6 2010-01-11 [expires: 2012-01-04]
|
96
|
+
sub 2048R/A18A54D6 2010-03-01 [expires: 2012-01-04]
|
97
|
+
sub 2048R/D53982CE 2010-08-31 [expires: 2012-01-04]
|
98
|
+
|
99
|
+
Even better would be obtaining the key fingerprint from me personally,
|
100
|
+
but this can often be impractical.
|
101
|
+
|
102
|
+
In any case, you should verify the key fingerprint listed in the
|
103
|
+
message from one of these alternate sources. If they match, the
|
104
|
+
signature is (hopefully) valid, assuming an attacker hasn't managed to
|
105
|
+
compromise rubygems, github, and my personal website.
|
106
|
+
|
107
|
+
If the fingerprints DO NOT match, you probably want to delete the
|
108
|
+
invalid key from your keyring:
|
109
|
+
|
110
|
+
gpg --delete-key <<KEY_ID>>
|
111
|
+
|
112
|
+
If you feel confident that the key is valid based on your external
|
113
|
+
fingerprint checks, you can make a signature on your gpg keyring. I
|
114
|
+
would advise making a local signature unless you've validated the
|
115
|
+
fingerprint in person. This means that you feel confident that the
|
116
|
+
key is valid, but you're not making any representations to the outside
|
117
|
+
world. To do so, run:
|
118
|
+
|
119
|
+
gpg --lsign <<KEY_ID>>
|
120
|
+
|
121
|
+
After this, you will no longer receive WARNINGs about untrusted
|
122
|
+
sources for any gems signed by this key/author.
|
123
|
+
|
124
|
+
Unfortunately, authentication is a hard problem. See my proposal
|
125
|
+
below for a potential solution to provide reasonable assurances about
|
126
|
+
key validity without having to manually confirm everything.
|
127
|
+
|
128
|
+
Motivation
|
129
|
+
----------
|
130
|
+
|
131
|
+
### Why we should sign gems with gpg
|
132
|
+
|
133
|
+
Gems are currently signed via X509 certificates generated by OpenSSL.
|
134
|
+
I don't think X509 signatures are the way to go. I think we should use
|
135
|
+
OpenPGP signatures instead.
|
136
|
+
|
137
|
+
1. Self-signed X509 certificates are basically worthless. There's no
|
138
|
+
easy way to verify that the key is legitimate. OpenPGP certificates
|
139
|
+
are designed to be generated by you, and then signed by other people
|
140
|
+
to validate their authenticity.
|
141
|
+
|
142
|
+
2. Setting up an X509 CA will take some resources. OpenPGP already
|
143
|
+
has a dedicated pool of servers run by volunteers at
|
144
|
+
pool.sks-keyservers.net.
|
145
|
+
|
146
|
+
3. The current generation policy isn't so good. Your private key
|
147
|
+
isn't encrypted. It's a strange file in a strange location that could
|
148
|
+
easily be lost. In gpg, all files are stored in ~/.gnupg. Private
|
149
|
+
keys are encrypted by default.
|
150
|
+
|
151
|
+
4. gpg has better tooling and documentation than openssl. There are
|
152
|
+
plenty of things like Seahorse or GPA to examine your keys. Policies
|
153
|
+
are documented and explained.
|
154
|
+
|
155
|
+
5. gpg allows the user to decide their default threat model and key
|
156
|
+
verification model. X509 assumes you trust the powers that be.
|
157
|
+
|
158
|
+
6. The OpenPGP certificate will (optionally) be tied to the owner's
|
159
|
+
real life id, if (for example) they sign release emails, use git's
|
160
|
+
signing functionality on release tags, sign binary releases. This
|
161
|
+
makes it easier to verify that the key isn't forged. (See trust model
|
162
|
+
3 below.)
|
163
|
+
|
164
|
+
The way I envision it, a gem maintainer would generate and publish a
|
165
|
+
key with gpg if they didn't already have one. He would put the key id
|
166
|
+
in the gem configuration file. When he builds the gem, gpg kicks in
|
167
|
+
and signs it.
|
168
|
+
|
169
|
+
An end user who wants to verify the key runs a command after fetching
|
170
|
+
the gem. If they have the key, we run gpg and verify the signature.
|
171
|
+
If not, we provide the key id so they can download it manually with
|
172
|
+
gpg.
|
173
|
+
|
174
|
+
The code to implement this should be pretty simple.
|
175
|
+
|
176
|
+
### Authenticating keys / Certificate authority
|
177
|
+
|
178
|
+
With gpg, the user can determine their trust model.
|
179
|
+
|
180
|
+
1. The current model. The user doesn't care. They don't check gpg
|
181
|
+
sigs. All is well. I imagine this will still be the model used by a
|
182
|
+
strong majority of users.
|
183
|
+
|
184
|
+
2. The user uses the OpenPGP web of trust. To be honest, this is a
|
185
|
+
PITA. It involves getting into the strong set by meeting people in
|
186
|
+
person and exchanging key fingerprints to make sure that there's no
|
187
|
+
man-in-the-middle attack. And even if the user is in the strong set,
|
188
|
+
there's no guarantee the gem maintainer is.
|
189
|
+
|
190
|
+
3. Continuity model. I downloaded the signing key for Ubuntu about four
|
191
|
+
releases ago. Even though I haven't done full verification, there
|
192
|
+
haven't been any reports of problems, and the next three releases were
|
193
|
+
signed by the same key. If the key changed and gpg couldn't verify the
|
194
|
+
next Ubuntu release, it would raise some eyebrows. You can use the same
|
195
|
+
philosophy with gems.
|
196
|
+
|
197
|
+
4. Simulated CA. Similar to the way a distributed source control system
|
198
|
+
can be used as a centralized system, the OpenPGP web of trust can be
|
199
|
+
setup to act as if there's a certificate authority.
|
200
|
+
|
201
|
+
For an example of option 4, look at the PGP Corp Global Directory[1].
|
202
|
+
You go to the website and submit your public key. It sends you an email
|
203
|
+
that you need to reply to. If you reply, signs your key and
|
204
|
+
publishes the information. If another user trusts the Global Directory
|
205
|
+
key, they will now trust your key.
|
206
|
+
|
207
|
+
Technically, this is subject to a man-in-the-middle attack. But it's
|
208
|
+
the same policy that gets used when I forget my password at something
|
209
|
+
like Amazon. And Amazon has my credit card info. I think the
|
210
|
+
procedure is valid against all but the most exotic attacks as long as
|
211
|
+
its limitations are known and documented.
|
212
|
+
|
213
|
+
[For conciseness' sake, I'm just going to pretend we've agreed that
|
214
|
+
rubygems.org is the Signing Authority. It will probably be a more
|
215
|
+
beta application, at least at first. Right now I'm more concerned
|
216
|
+
with presenting the model.]
|
217
|
+
|
218
|
+
rubygems.org could:
|
219
|
+
|
220
|
+
1. Allow gem publisher to upload a private key from their account page.
|
221
|
+
|
222
|
+
2. Upon receipt of key, send an email to the gem publisher's email
|
223
|
+
containing an encrypted token.
|
224
|
+
|
225
|
+
3. The gem publisher decrypts the token,
|
226
|
+
|
227
|
+
4. The gem publisher posts the decrypted token onto a form at the
|
228
|
+
website and submits. This establishes the gem publisher has control of
|
229
|
+
(a) the email address, and (b) the OpenPGP key. (Excluding a possible
|
230
|
+
mitm at the network level.)
|
231
|
+
|
232
|
+
5. rubygems.org signs the key with it's own signing key, possibly with a
|
233
|
+
6 month or 1 year expiration date.
|
234
|
+
|
235
|
+
6. The new signature is submitted to the keyservers at
|
236
|
+
pool.sks-keyservers.net, making the verification available world-wide.
|
237
|
+
|
238
|
+
Now an unrelated gem user can configure gpg to trust the rubygems
|
239
|
+
signing key. When they download the gem from above and retrieve the gem
|
240
|
+
publisher's key, they will see that the key is valid because it's
|
241
|
+
trusted by rubygems. If it's not trusted, it's up to User B to
|
242
|
+
investigate and determine if they trust the gem or not.
|
243
|
+
|
244
|
+
Note that the relationship between these keys isn't contained in the
|
245
|
+
gem. It's contained on the keyservers. If another website or mirror
|
246
|
+
provides the same gem with the same signature, it will still show up as
|
247
|
+
valid, assuming the gem user trusts the rubygems.org signing key.
|
248
|
+
|
249
|
+
### In the year 2038
|
250
|
+
|
251
|
+
Assuming all goes well, most people are signing their gems, and the
|
252
|
+
community likes the feature, we could configure a keyring for use by
|
253
|
+
gems only, similar to the way apt-get maintains its own keyring.
|
254
|
+
|
255
|
+
This keyring would automatically include the rubygems.org signing key on
|
256
|
+
installation. When downloading a new gem, verification will happen
|
257
|
+
automatically. If the key isn't on the gem keyring it will be
|
258
|
+
downloaded automatically. If the key isn't trusted, the user will
|
259
|
+
receive a warning and asked if they want to continue. If the signature
|
260
|
+
check fails, the gem will not be installed.
|
261
|
+
|
262
|
+
[1] https://keyserver.pgp.com/vkd/GetWelcomeScreen.event
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "rubygems/command"
|
2
|
+
require 'rubygems/version_option'
|
3
|
+
|
4
|
+
class Gem::Commands::SbuildCommand < Gem::Command
|
5
|
+
|
6
|
+
include Gem::VersionOption
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super 'sbuild', 'Build your gem, then sign it with OpenPGP'
|
10
|
+
|
11
|
+
add_version_option
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def arguments
|
16
|
+
"GEMNAME name of gem to build"
|
17
|
+
end
|
18
|
+
|
19
|
+
def defaults_str
|
20
|
+
""
|
21
|
+
end
|
22
|
+
|
23
|
+
def usage
|
24
|
+
"blah blah"
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute
|
28
|
+
version = options[:version] || Gem::Requirement.default
|
29
|
+
|
30
|
+
raise "Not implemented yet"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "rubygems/command"
|
2
|
+
require "rubygems/package"
|
3
|
+
require 'rubygems/version_option'
|
4
|
+
require "rubygems/gem_openpgp"
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
class Gem::Commands::SignCommand < Gem::Command
|
8
|
+
|
9
|
+
include Gem::VersionOption
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super 'sign', 'Sign existing gem with your OpenPGP key', :key => nil
|
13
|
+
|
14
|
+
add_version_option
|
15
|
+
|
16
|
+
add_option('--key KEY', "Specify key id if you don't want to use your default gpg key") do |key, options|
|
17
|
+
options[:key] = key
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def arguments
|
22
|
+
"GEMNAME name of gem to sign"
|
23
|
+
end
|
24
|
+
|
25
|
+
def defaults_str
|
26
|
+
""
|
27
|
+
end
|
28
|
+
|
29
|
+
def usage
|
30
|
+
"blah blah"
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute
|
34
|
+
version = options[:version] || Gem::Requirement.default
|
35
|
+
gem, specs = get_one_gem_name, []
|
36
|
+
|
37
|
+
unsigned_gem = gem + ".unsigned"
|
38
|
+
FileUtils.mv gem, unsigned_gem
|
39
|
+
|
40
|
+
unsigned_gem_file = File.open(unsigned_gem, "r")
|
41
|
+
signed_gem_file = File.open(gem, "w")
|
42
|
+
|
43
|
+
signed_gem = Gem::Package::TarWriter.new(signed_gem_file)
|
44
|
+
|
45
|
+
Gem::Package::TarReader.new(unsigned_gem_file).each do |f|
|
46
|
+
say f.full_name.inspect
|
47
|
+
|
48
|
+
if f.full_name[-4..-1] == ".asc"
|
49
|
+
say "Skipping old signature file #{f.full_name}"
|
50
|
+
next
|
51
|
+
end
|
52
|
+
|
53
|
+
say "Signing #{f.full_name.inspect}..."
|
54
|
+
|
55
|
+
file_contents = f.read()
|
56
|
+
|
57
|
+
signed_gem.add_file(f.full_name, 0644) do |outfile|
|
58
|
+
outfile.write(file_contents)
|
59
|
+
end
|
60
|
+
|
61
|
+
signed_gem.add_file(f.full_name + ".asc", 0644) do |outfile|
|
62
|
+
outfile.write(Gem::OpenPGP.detach_sign(file_contents,options[:key]))
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
rescue Exception => ex
|
67
|
+
FileUtils.mv unsigned_gem_file, gem
|
68
|
+
raise
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "rubygems/command"
|
2
|
+
require "rubygems/package"
|
3
|
+
require 'rubygems/version_option'
|
4
|
+
require "rubygems/gem_openpgp"
|
5
|
+
|
6
|
+
class Gem::Commands::VerifyCommand < Gem::Command
|
7
|
+
|
8
|
+
include Gem::VersionOption
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
super 'verify', 'Verify gem with your OpenPGP key'
|
12
|
+
|
13
|
+
add_version_option
|
14
|
+
|
15
|
+
add_option('--get-key', "If the key is not available, download it from a keyserver") do |key, options|
|
16
|
+
options[:get_key] = true
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def arguments
|
22
|
+
"GEMNAME name of gem to verify"
|
23
|
+
end
|
24
|
+
|
25
|
+
def defaults_str
|
26
|
+
""
|
27
|
+
end
|
28
|
+
|
29
|
+
def usage
|
30
|
+
"blah blah"
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute
|
34
|
+
version = options[:version] || Gem::Requirement.default
|
35
|
+
gem, specs = get_one_gem_name, []
|
36
|
+
|
37
|
+
file = File.open(gem,"r")
|
38
|
+
|
39
|
+
tar_files = {}
|
40
|
+
|
41
|
+
Gem::Package::TarReader.new(file).each do |f|
|
42
|
+
tar_files[f.full_name] = f.read()
|
43
|
+
end
|
44
|
+
|
45
|
+
tar_files.keys.each do |file_name|
|
46
|
+
next if file_name[-4..-1] == ".asc"
|
47
|
+
say "Verifying #{file_name}..."
|
48
|
+
|
49
|
+
sig_file_name = file_name + ".asc"
|
50
|
+
if !tar_files.has_key? sig_file_name
|
51
|
+
say "WARNING!!! No sig found for #{file_name}"
|
52
|
+
next
|
53
|
+
end
|
54
|
+
|
55
|
+
Gem::OpenPGP.verify(tar_files[file_name], tar_files[sig_file_name], options[:get_key])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "rubygems/command"
|
2
|
+
require 'rubygems/version_option'
|
3
|
+
|
4
|
+
class Gem::Commands::VinstallCommand < Gem::Command
|
5
|
+
|
6
|
+
include Gem::VersionOption
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super 'vinstall', 'verify gem with GPG, and only install if sig check passes'
|
10
|
+
|
11
|
+
add_version_option
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def arguments
|
16
|
+
"GEMNAME name of gem to build"
|
17
|
+
end
|
18
|
+
|
19
|
+
def defaults_str
|
20
|
+
""
|
21
|
+
end
|
22
|
+
|
23
|
+
def usage
|
24
|
+
"blah blah"
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute
|
28
|
+
version = options[:version] || Gem::Requirement.default
|
29
|
+
|
30
|
+
puts "Not implemented yet."
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module Gem::OpenPGP
|
5
|
+
def self.openpgp_available?
|
6
|
+
`gpg --version`
|
7
|
+
$? == 0
|
8
|
+
rescue
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.detach_sign data, key_id=nil
|
13
|
+
key_flag = ""
|
14
|
+
key_flag = "-u #{key_id}" if key_id
|
15
|
+
cmd = "gpg #{key_flag} --detach-sign --armor"
|
16
|
+
exit_status = nil
|
17
|
+
sig,err = Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
18
|
+
stdin.write data
|
19
|
+
stdin.close
|
20
|
+
exit_status = wait_thr.value
|
21
|
+
[stdout.read(), stderr.read()]
|
22
|
+
end
|
23
|
+
|
24
|
+
raise "gpg error #{err}" if exit_status != 0
|
25
|
+
|
26
|
+
sig
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.verify data, sig, get_key=false
|
30
|
+
data_file = Tempfile.new("rubygems_data")
|
31
|
+
data_file.write(data)
|
32
|
+
data_file.close
|
33
|
+
|
34
|
+
sig_file = Tempfile.new("rubygems_sig")
|
35
|
+
sig_file.write(sig)
|
36
|
+
sig_file.close
|
37
|
+
|
38
|
+
get_key_params = "--keyserver pool.sks-keyservers.net --keyserver-options auto-key-retrieve"
|
39
|
+
get_key_params = "" if get_key != true
|
40
|
+
|
41
|
+
cmd = "gpg #{get_key_params} --verify #{sig_file.path} #{data_file.path}"
|
42
|
+
exit_status = nil
|
43
|
+
res, err = Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
44
|
+
stdin.close
|
45
|
+
exit_status = wait_thr.value
|
46
|
+
[ stdout.read(), stderr.read() ]
|
47
|
+
end
|
48
|
+
|
49
|
+
color_code = if exit_status == 0
|
50
|
+
"32"
|
51
|
+
else
|
52
|
+
"31"
|
53
|
+
end
|
54
|
+
|
55
|
+
puts "\033[#{color_code}m#{err}\033[0m"
|
56
|
+
puts "\033[37m #{res} \033[0m"
|
57
|
+
|
58
|
+
raise "gpg encountered errors! #{err}" if exit_status != 0
|
59
|
+
end
|
60
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubygems-openpgp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Grant Olson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2010-05-27 00:00:00.000000000 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
description: Digitally sign gems via OpenPGP instead of OpenSSL
|
16
|
+
email: kgo@grant-olson.net
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files:
|
20
|
+
- README.md
|
21
|
+
files:
|
22
|
+
- LICENSE
|
23
|
+
- lib/rubygems_plugin.rb
|
24
|
+
- lib/rubygems/commands/verify_command.rb
|
25
|
+
- lib/rubygems/commands/vinstall_command.rb
|
26
|
+
- lib/rubygems/commands/sbuild_command.rb
|
27
|
+
- lib/rubygems/commands/sign_command.rb
|
28
|
+
- lib/rubygems/gem_openpgp.rb
|
29
|
+
- README.md
|
30
|
+
has_rdoc: true
|
31
|
+
homepage: https://github.com/grant-olson/rubygems-openpgp
|
32
|
+
licenses:
|
33
|
+
- BSD 3 Clause
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 1.6.2
|
53
|
+
signing_key:
|
54
|
+
specification_version: 3
|
55
|
+
summary: Sign gems via OpenPGP
|
56
|
+
test_files: []
|
metadata.gz.asc
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
-----BEGIN PGP SIGNATURE-----
|
2
|
+
Version: GnuPG v1.4.10 (GNU/Linux)
|
3
|
+
|
4
|
+
iQEcBAABAwAGBQJN4YzYAAoJEP5F5V2hilTWyxUH/2+P4ieweDXKgi+8wvxQlwPC
|
5
|
+
SicpO2/uYz39KK4qlqW5rJxxgjaBaAiGdofAdwhM6+HOOOeanx6tYK+bq9vxBFLF
|
6
|
+
mfAvyYFWbfv41pxjWlgBpjLoU+x9J8ewcyv8jtrLop2qT8TOc4C9/9N9zpVDTLk2
|
7
|
+
YX7QEwCTuvM3G4IrN0YRZ//pm70yR321NV36qbycb6q7JKEpyyutksnE9ketjc6i
|
8
|
+
N0XEaUOL7xzGHSLMgnzR8DPvtauWraERdVatmQYsnmn5I+4+yRAOd/gYVy+T+V23
|
9
|
+
mKqjpox3R6aav1PN1tNelvWPBpk574bEZVfFwuCZVMqYvsTEFegLUl/6yAacF2s=
|
10
|
+
=/mom
|
11
|
+
-----END PGP SIGNATURE-----
|