|
List Info
Thread: RubyGems 0.9.0 Signing Updates
|
|
| RubyGems 0.9.0 Signing Updates |

|
2006-08-31 07:44:11 |
Hi All,
Attached is a small patch against RubyGems 0.9.0 which adds
the
following:
* Ensures that the trust directory exists and is a
directory
before trying to add a certificate to the trust store.
* Ensures that permissions on the trust directory and
generated
certificates and keys are sufficiently restrictive.
On the off-chance that this patch gets mangled in transit,
it's also
available on the web at the following URL:
http://pablotron.org/files/rubygems-0.9.0-signing_
updates.diff
For the security-conscious among you, an OpenPGP signature
of the
aforementioned patch can be found here:
http://pablotron.org/files/rubygems-0.9.0-sign
ing_updates.diff.asc
It's a relatively small set of changes. That said,
questions, comments,
and unadulterated vitriol are always appreciated.
--
Paul Duncan <pabs pablotron.org> OpenPGP Key ID:
0x82C29562
http://www.pablotron.org/
a> http://www.paulduncan.org/
diff -ur rubygems-0.9.0/lib/rubygems/security.rb
rubygems-0.9.0-fix_add_cert/lib/rubygems/security.rb
--- rubygems-0.9.0/lib/rubygems/security.rb 2006-06-06
23:39:54.000000000 -0400
+++
rubygems-0.9.0-fix_add_cert/lib/rubygems/security.rb 2006-08
-31 03:17:32.000000000 -0400
 -95,6
+95,14 
# output directory for trusted certificate checksums
:trust_dir => File::join(Gem.user_home, '.gem',
'trust'),
+
+ # default permissions for trust directory and certs
+ :perms => {
+ :trust_dir => 0700,
+ :trusted_cert => 0600,
+ :signing_cert => 0600,
+ :signing_key => 0600,
+ },
}
#
 -342,6
+350,32 
end
#
+ # Make sure the trust directory exists. If it does
exist, make sure
+ # it's actually a directory. If not, then create it
with the
+ # appropriate permissions.
+ #
+ def self.verify_trust_dir(opt)
+ # grab path from options
+ path = opt[:trust_dir]
+
+ # if the directory exists, then make sure it is in
fact a
+ # directory. if it doesn't exist, then create it
with the
+ # appropriate permissions
+ if File.exists?(path)
+ # verify that the trust directory is actually a
directory
+ unless File.directory?(path)
+ err = "trust directory # isn't a
directory"
+ raise Gem::Security::Exception, err
+ end
+ else
+ # trust directory doesn't exist, so create it with
+ # permissions
+ FileUtils.mkdir_p(path)
+ FileUtils.chmod(opt[:perms][:trust_dir], path)
+ end
+ end
+
+ #
# Build a certificate from the given DN and private
key.
#
def self.build_cert(name, key, opt = {})
 -394,13
+428,16 
# build private key
key = opt[:key_algo].new(opt[:key_size])
- # create the trust directory if it doesn't exist
- FileUtils::mkdir_p(opt[:trust_dir]) unless
File.exists?(opt[:trust_dir])
+ # method name pretty much says it all
+ verify_trust_dir(opt)
# if we're saving the key, then write it out
if opt[:save_key]
path[:key] = opt[:save_key_path] ||
(opt[:output_fmt] % 'private_key')
- File.open(path[:key], 'wb') { |file|
file.write(key.to_pem) }
+ File.open(path[:key], 'wb') do |file|
+ file.chmod(opt[:perms][:signing_key])
+ file.write(key.to_pem)
+ end
end
# build self-signed public cert from key
 -409,7
+446,10 
# if we're saving the cert, then write it out
if opt[:save_cert]
path[:cert] = opt[:save_cert_path] ||
(opt[:output_fmt] % 'public_cert')
- File.open(path[:cert], 'wb') { |file|
file.write(cert.to_pem) }
+ File.open(path[:cert], 'wb') do |file|
+ file.chmod(opt[:perms][:signing_cert])
+ file.write(cert.to_pem)
+ end
end
# return key, cert, and paths (if applicable)
 -429,8
+469,14 
# get destination path
path = Gem::Security::Policy.trusted_cert_path(cert,
opt)
+ # verify trust directory (can't write to nowhere,
you know)
+ verify_trust_dir(opt)
+
# write cert to output file
- File.open(path, 'wb') { |file|
file.write(cert.to_pem) }
+ File.open(path, 'wb') do |file|
+ file.chmod(opt[:perms][:trusted_cert])
+ file.write(cert.to_pem)
+ end
# return nil
nil
_______________________________________________
Rubygems-developers mailing list
Rubygems-developers rubyforge.org
http://rubyforge.org/mailman/listinfo/rubygems-develope
rs |
|
| RubyGems 0.9.0 Signing Updates |

|
2006-08-31 17:42:50 |
On Aug 31, 2006, at 12:44 AM, Paul Duncan wrote:
> Hi All,
>
> Attached is a small patch against RubyGems 0.9.0 which
adds the
> following:
>
> * Ensures that the trust directory exists and is a
directory
> before trying to add a certificate to the trust
store.
> * Ensures that permissions on the trust directory and
generated
> certificates and keys are sufficiently restrictive.
>
> On the off-chance that this patch gets mangled in
transit, it's also
> available on the web at the following URL:
>
> http://pablotron.org/files/rubygems-0.9.0-signing_
updates.diff
>
> For the security-conscious among you, an OpenPGP
signature of the
> aforementioned patch can be found here:
>
> http://pablotron.org/files/rubygems-0.9.0-sign
ing_updates.diff.asc
>
> It's a relatively small set of changes. That said,
questions,
> comments,
> and unadulterated vitriol are always appreciated.
>
> diff -ur rubygems-0.9.0/lib/rubygems/security.rb
rubygems-0.9.0-
> fix_add_cert/lib/rubygems/security.rb
> --- rubygems-0.9.0/lib/rubygems/security.rb 2006-06-06
> 23:39:54.000000000 -0400
> +++
rubygems-0.9.0-fix_add_cert/lib/rubygems/security.rb 2006-08
-31
> 03:17:32.000000000 -0400
>  -342,6 +350,32 
> end
>
> #
> + # Make sure the trust directory exists. If it
does exist,
> make sure
> + # it's actually a directory. If not, then create
it with the
> + # appropriate permissions.
> + #
> + def self.verify_trust_dir(opt)
> + # grab path from options
> + path = opt[:trust_dir]
opt[:trust_dir]
> +
> + # if the directory exists, then make sure it is
in fact a
> + # directory. if it doesn't exist, then create
it with the
> + # appropriate permissions
> + if File.exists?(path)
File.exists? is deprecated, use File.exist.
> + # verify that the trust directory is actually
a directory
> + unless File.directory?(path)
> + err = "trust directory # isn't
a directory"
> + raise Gem::Security::Exception, err
> + end
> + else
> + # trust directory doesn't exist, so create it
with
> + # permissions
> + FileUtils.mkdir_p(path)
> + FileUtils.chmod(opt[:perms][:trust_dir], path)
and opt[:perms][:trust_dir] are the only things in opt you
use here,
why not make them explicit arguments?
> + end
> + end
> +
> + #
> # Build a certificate from the given DN and
private key.
> #
> def self.build_cert(name, key, opt = {})
>  -429,8 +469,14 
> # get destination path
> path =
Gem::Security::Policy.trusted_cert_path(cert, opt)
>
> + # verify trust directory (can't write to
nowhere, you know)
> + verify_trust_dir(opt)
> +
> # write cert to output file
> - File.open(path, 'wb') { |file|
file.write(cert.to_pem) }
> + File.open(path, 'wb') do |file|
> + file.chmod(opt[:perms][:trusted_cert])
> + file.write(cert.to_pem)
> + end
>
> # return nil
> nil
--
Eric Hodel - drbrain segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant
http://trackmap.robotco
op.com
_______________________________________________
Rubygems-developers mailing list
Rubygems-developers rubyforge.org
http://rubyforge.org/mailman/listinfo/rubygems-develope
rs
|
|
| RubyGems 0.9.0 Signing Updates |

|
2006-08-31 19:19:03 |
* Eric Hodel (drbrain segment7.net) wrote:
[snipped]
> File.exists? is deprecated, use File.exist.
You sir, are correct.
[snipped]
> and opt[:perms][:trust_dir] are the only things in opt
you use here,
> why not make them explicit arguments?
I did it that way for consistency with the other calls.
That said, I
see the advantage of the approach you're suggesting:
without a fancy
hash of options, the method is usable elsewhere.
I've updated the patch with both suggested changes. The
new patch is
attached. It's also available online at the following
URLs:
http://pablotron.org/files/rubygems-0.9.0-signin
g_updates-2.diff
http://pablotron.org/files/rubygems-0.9.0-si
gning_updates-2.diff.asc
Thanks!
> --
> Eric Hodel - drbrain segment7.net - http://blog.segment7.net
> This implementation is HODEL-HASH-9600 compliant
--
Paul Duncan <pabs pablotron.org> OpenPGP Key ID:
0x82C29562
http://www.pablotron.org/
a> http://www.paulduncan.org/
diff -ur rubygems-0.9.0/lib/rubygems/package.rb
rubygems-0.9.0-fix_add_cert/lib/rubygems/package.rb
--- rubygems-0.9.0/lib/rubygems/package.rb 2006-06-13
23:39:45.000000000 -0400
+++
rubygems-0.9.0-fix_add_cert/lib/rubygems/package.rb 2006-08-
31 14:58:01.000000000 -0400
 -525,7
+525,7 
if
Gem::Security.constants.index(security_policy)
# load one of the pre-defined security
policies
security_policy =
Gem::Security.const_get(security_policy)
- elsif File.exists?(security_policy)
+ elsif File.exist?(security_policy)
# FIXME: this doesn't work yet
security_policy =
YAML::load(File.read(security_policy))
else
diff -ur rubygems-0.9.0/lib/rubygems/security.rb
rubygems-0.9.0-fix_add_cert/lib/rubygems/security.rb
--- rubygems-0.9.0/lib/rubygems/security.rb 2006-06-06
23:39:54.000000000 -0400
+++
rubygems-0.9.0-fix_add_cert/lib/rubygems/security.rb 2006-08
-31 14:57:37.000000000 -0400
 -95,6
+95,14 
# output directory for trusted certificate checksums
:trust_dir => File::join(Gem.user_home, '.gem',
'trust'),
+
+ # default permissions for trust directory and certs
+ :perms => {
+ :trust_dir => 0700,
+ :trusted_cert => 0600,
+ :signing_cert => 0600,
+ :signing_key => 0600,
+ },
}
#
 -216,7
+224,7 
'Untrusted Signing Chain Root',
root.subject.to_s,
"path \"#\" does
not exist",
- ] unless File.exists?(path)
+ ] unless File.exist?(path)
# load calculate digest from saved cert file
save_cert =
OpenSSL::X509::Certificate.new(File.read(path))
 -342,6
+350,29 
end
#
+ # Make sure the trust directory exists. If it does
exist, make sure
+ # it's actually a directory. If not, then create it
with the
+ # appropriate permissions.
+ #
+ def self.verify_trust_dir(path, perms)
+ # if the directory exists, then make sure it is in
fact a
+ # directory. if it doesn't exist, then create it
with the
+ # appropriate permissions
+ if File.exist?(path)
+ # verify that the trust directory is actually a
directory
+ unless File.directory?(path)
+ err = "trust directory # isn't a
directory"
+ raise Gem::Security::Exception, err
+ end
+ else
+ # trust directory doesn't exist, so create it with
+ # permissions
+ FileUtils.mkdir_p(path)
+ FileUtils.chmod(perms, path)
+ end
+ end
+
+ #
# Build a certificate from the given DN and private
key.
#
def self.build_cert(name, key, opt = {})
 -394,13
+425,16 
# build private key
key = opt[:key_algo].new(opt[:key_size])
- # create the trust directory if it doesn't exist
- FileUtils::mkdir_p(opt[:trust_dir]) unless
File.exists?(opt[:trust_dir])
+ # method name pretty much says it all
+ verify_trust_dir(opt[:trust_dir],
opt[:perms][:trust_dir])
# if we're saving the key, then write it out
if opt[:save_key]
path[:key] = opt[:save_key_path] ||
(opt[:output_fmt] % 'private_key')
- File.open(path[:key], 'wb') { |file|
file.write(key.to_pem) }
+ File.open(path[:key], 'wb') do |file|
+ file.chmod(opt[:perms][:signing_key])
+ file.write(key.to_pem)
+ end
end
# build self-signed public cert from key
 -409,7
+443,10 
# if we're saving the cert, then write it out
if opt[:save_cert]
path[:cert] = opt[:save_cert_path] ||
(opt[:output_fmt] % 'public_cert')
- File.open(path[:cert], 'wb') { |file|
file.write(cert.to_pem) }
+ File.open(path[:cert], 'wb') do |file|
+ file.chmod(opt[:perms][:signing_cert])
+ file.write(cert.to_pem)
+ end
end
# return key, cert, and paths (if applicable)
 -429,8
+466,14 
# get destination path
path = Gem::Security::Policy.trusted_cert_path(cert,
opt)
+ # verify trust directory (can't write to nowhere,
you know)
+ verify_trust_dir(opt[:trust_dir],
opt[:perms][:trust_dir])
+
# write cert to output file
- File.open(path, 'wb') { |file|
file.write(cert.to_pem) }
+ File.open(path, 'wb') do |file|
+ file.chmod(opt[:perms][:trusted_cert])
+ file.write(cert.to_pem)
+ end
# return nil
nil
 -460,7
+503,7 
# convert it into a cert object, and if it's a
cert object,
# leave it alone
if cert &&
!cert.kind_of?(OpenSSL::X509::Certificate)
- cert = File.read(cert) if File::exists?(cert)
+ cert = File.read(cert) if File::exist?(cert)
cert = OpenSSL::X509::Certificate.new(cert)
end
cert
_______________________________________________
Rubygems-developers mailing list
Rubygems-developers rubyforge.org
http://rubyforge.org/mailman/listinfo/rubygems-develope
rs |
|
[1-3]
|
|