More on DRB & OpenSSL

OK, I’ve tracked down my problem with DRb and OpenSSL a bit more; perhaps
someone can help me out now, as I’m quickly getting out of my league. Here
are test client and server scripts that will show the failure. To run them,
you’ll need the latest DRb from ruby CVS
(http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/lib/drb) installed (and of
course the OpenSSL extension).

s.rb:

require 'drb’
require ‘drb/ssl’

class Front
def small
puts “Called #small
"Hi!"
end

def large
  puts "Called #large"
  "a" * 1000 * 500
end

end

url = ARGV[0] or raise "You must supply the url"
config = {
:SSLCertName => [ [“C”,“US”], [“O”,“someplace”], [“CN”, “Temporary”] ],
:verbose => true
}
DRb.start_service(url, Front::new, config)
puts "Listening on #{url}"
DRb.thread.join

c.rb:

require 'drb’
require ‘drb/ssl’

url = ARGV[0] or raise "You must supply the url"
DRb.start_service
front = DRbObject::new(nil, url)
puts "Connected to #{url}"
p front.small.size
p front.large.size

s.rb output:

ntalbott@proxytest:~$ ruby -vw s.rb drbssl://localhost:5777
ruby 1.8.0 (2003-08-04) [i386-linux]
.++++++++++++
…++++++++++++
Listening on drbssl://localhost:5777
Called #small
Called #large
s.rb:23:in `join’: Interrupt from s.rb:23

c.rb output:

ntalbott@proxytest:~$ ruby -vw c.rb drbssl://localhost:5777
ruby 1.8.0 (2003-08-04) [i386-linux]
Connected to drbssl://localhost:5777
3
(Hangs until server is interrupted)
500000

If there’s any other information I can provide, or anything else I can do to
help debug this, please let me know. Also, if there are other places I
should ask this question, please let me know that, too.

Thanks,

Nathaniel

<:((><

Nathaniel Talbott wrote:

OK, I’ve tracked down my problem with DRb and OpenSSL a bit more; perhaps
someone can help me out now, as I’m quickly getting out of my league. Here
are test client and server scripts that will show the failure. To run them,
you’ll need the latest DRb from ruby CVS
(http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/lib/drb) installed (and of
course the OpenSSL extension).

s.rb:

require ‘drb’
require ‘drb/ssl’

class Front
def small
puts “Called #small
“Hi!”
end

def large
puts “Called #large
“a” * 1000 * 500
end
end

url = ARGV[0] or raise “You must supply the url”
config = {
:SSLCertName => [ [“C”,“US”], [“O”,“someplace”], [“CN”, “Temporary”] ],
:verbose => true
}
DRb.start_service(url, Front::new, config)
puts “Listening on #{url}”
DRb.thread.join

c.rb:

require ‘drb’
require ‘drb/ssl’

url = ARGV[0] or raise “You must supply the url”
DRb.start_service
front = DRbObject::new(nil, url)
puts “Connected to #{url}”
p front.small.size
p front.large.size

s.rb output:

ntalbott@proxytest:~$ ruby -vw s.rb drbssl://localhost:5777
ruby 1.8.0 (2003-08-04) [i386-linux]
.++++++++++++
…++++++++++++
Listening on drbssl://localhost:5777
Called #small
Called #large
s.rb:23:in `join’: Interrupt from s.rb:23

c.rb output:

ntalbott@proxytest:~$ ruby -vw c.rb drbssl://localhost:5777
ruby 1.8.0 (2003-08-04) [i386-linux]
Connected to drbssl://localhost:5777
3
(Hangs until server is interrupted)
500000

If there’s any other information I can provide, or anything else I can do to
help debug this, please let me know. Also, if there are other places I
should ask this question, please let me know that, too.

Thanks,

Nathaniel

<:((><

I’ve noticed that there is always a strange silence on DRb questions. I
wonder how many people really use it. I love it, well, I love what I
know about it. The docs seems a little hard to come by.

Michael

Hi,

From: “Nathaniel Talbott” nathaniel@NOSPAMtalbott.ws
Sent: Thursday, August 07, 2003 7:45 AM

OK, I’ve tracked down my problem with DRb and OpenSSL a bit more; perhaps
someone can help me out now, as I’m quickly getting out of my league. Here
are test client and server scripts that will show the failure. To run them,
you’ll need the latest DRb from ruby CVS
(http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/lib/drb) installed (and of
course the OpenSSL extension).

Reproduced on my cygwin box.
SSL client stacks at sysread after readable-check in openssl/buffering.rb.
I’m talking to gotoyuzo about this problem.

Regards,
// NaHi

For some reason the IO.select in openssl/buffering.rb is stalling. It
looks to be a problem in ossl.c.

/usr/local/lib/ruby/1.8/openssl/buffering.rb:31:in select': Interrupt from /usr/local/lib/ruby/1.8/openssl/buffering.rb:31:in fill_rbuff’
from /usr/local/lib/ruby/1.8/openssl/buffering.rb:58:in read' from /usr/local/lib/ruby/site_ruby/1.8/drb/drb.rb:108:in load’

You can solve the problem for now by providing IO.select with a timeout.
I’m using 1.5 seconds below. (see following patch).

It’s stopping on an IO#select on the 482nd iteration hitting IO.select.
This means that there is a current limitation in the OpenSSL module of
481 * BLOCK_SIZE. It looks to me like the Buffering module works fine,
leaving the underlying sysread, IO functions in ossl.c under inspection.

Oh, and this problem is affecting the client only.

_why

— openssl.orig/lib/openssl/buffering.rb Wed Jul 23 10:11:30 2003
+++ openssl/lib/openssl/buffering.rb Wed Aug 6 23:06:59 2003
@@ -17,7 +17,7 @@
module Buffering
include Enumerable
attr_accessor :sync

  • BLOCK_SIZE = 1024
  • BLOCK_SIZE = 4096
···

Nathaniel Talbott (nathaniel@NOSPAMtalbott.ws) wrote:

OK, I’ve tracked down my problem with DRb and OpenSSL a bit more; perhaps
someone can help me out now, as I’m quickly getting out of my league. Here
are test client and server scripts that will show the failure. To run them,
you’ll need the latest DRb from ruby CVS

for reading.

@@ -28,7 +28,7 @@
@rbuffer = “” unless defined? @rbuffer
begin
if self.respond_to?(:to_io)

  •    IO.select([self.to_io], nil, nil)
    
  •    IO.select([self.to_io], nil, nil, 1.5)
     end
     @rbuffer << self.sysread(BLOCK_SIZE)
    
    rescue EOFError

I’ve noticed that there is always a strange silence on DRb questions. I
wonder how many people really use it. I love it, well, I love what I
know about it. The docs seems a little hard to come by.

This is something we should change – anyone want to work on an
initially wiki-based (english) documentation of dRB with me? It’s
something I could enjoy delving deeply into, and I think that some
extensions could be useful as well.

I’d host the wiki unless someone else really cares to – I’ve a server
on a dual T-1 to offer, and a DS-3 coming in October. Bandwidth and CPU
are cheap :wink:

Ari

···

Michael

You think docs are hard to come by for DRb, wait until you try using
OpenSSL, or even better, OpenSSL with DRb. It’s called reading the code :-/.
Anyhow, DRb has been working great for me, and even the SSL part, with some
figuring out, is doing OK. This problem, though, has me tearing my hair out.
It’s not very useful to only be able to send small messages across DRb.

I’ll let you know how it turns out.

Nathaniel

<:((><

···

Michael Garriss [mailto:mgarriss@earthlink.net] wrote:

I’ve noticed that there is always a strange silence on DRb
questions. I
wonder how many people really use it. I love it, well, I love what I
know about it. The docs seems a little hard to come by.

Excellent! It’s great to have somebody looking at this.

Just for another data point, when I was doing my investigation, I saw it
block both at the IO.select (as why says) and at the SSLSocket#sysread. Both
times the blocking was happening on the client side.

Thanks,

Nathaniel

<:((><

···

NAKAMURA, Hiroshi [mailto:nahi@keynauts.com] wrote:

From: “Nathaniel Talbott” nathaniel@NOSPAMtalbott.ws
Sent: Thursday, August 07, 2003 7:45 AM

OK, I’ve tracked down my problem with DRb and OpenSSL a bit more;
perhaps someone can help me out now, as I’m quickly getting
out of my
league. Here are test client and server scripts that will show the
failure. To run them, you’ll need the latest DRb from ruby CVS
(http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/lib/drb)
installed (and
of course the OpenSSL extension).

Reproduced on my cygwin box.
SSL client stacks at sysread after readable-check in
openssl/buffering.rb. I’m talking to gotoyuzo about this problem.

For some reason the IO.select in openssl/buffering.rb is
stalling. It looks to be a problem in ossl.c.

From looking at the code in ossl.c, I thought the problem might be in
SSL_read, or the use of it. The documentation
(http://www.openssl.org/docs/ssl/SSL_read.html) seemed to be about as clear
as mud about how that function works, though.

You can solve the problem for now by providing IO.select with
a timeout. I’m using 1.5 seconds below. (see following patch).

This is excellent! I didn’t know you could provide a timeout to IO#select.
Now I can actually deploy my code. Thanks!

It’s stopping on an IO#select on the 482nd iteration hitting
IO.select. This means that there is a current limitation in
the OpenSSL module of 481 * BLOCK_SIZE. It looks to me like
the Buffering module works fine, leaving the underlying
sysread, IO functions in ossl.c under inspection.

Oh, and this problem is affecting the client only.

That’s what I observed as well.

How do you find time to write about all that’s cool in Ruby 1.8.0, work on
YAML/Syck, research OpenSSL problems, and the million other things I’m sure
you do? :slight_smile:

Thanks,

Nathaniel

<:((><

···

why the lucky stiff [mailto:ruby-talk@whytheluckystiff.net] wrote:

I’d suggest starting with RDoc’ing the library. The folks over on the
ruby-doc list are currently working on RDoc’ing all of the standard library,
and if you (or anyone else) wanted to tackle DRb, I’m sure they’d love it. I
know I would :-).

Nathaniel

<:((><

···

Aredridel [mailto:aredridel@nbtsc.org] wrote:

I’ve noticed that there is always a strange silence on DRb questions.
I wonder how many people really use it. I love it, well, I love what
I know about it. The docs seems a little hard to come by.

This is something we should change – anyone want to work on
an initially wiki-based (english) documentation of dRB with
me? It’s something I could enjoy delving deeply into, and I
think that some extensions could be useful as well.

I’ve noticed that there is always a strange silence on DRb questions. I
[…]
This is something we should change – anyone want to work on an
initially wiki-based (english) documentation of dRB with me? It’s

I scratched together some notes at:

http://www.eng.cse.dmu.ac.uk/~hgs/ruby/dRuby/

but I don’t think I got everything right. Feel free to use this if
it is of any use at all. That’s why I wrote it somewhere visible.

I’ve not got into SSL with this yet, I’m using SHA1’s of
(nonce + passwd)s to authenticate messages at the moment.

Ari

    Hugh
···

On Thu, 7 Aug 2003, Aredridel wrote:

wrote (more or less):

I’ve noticed that there is always a strange silence on DRb questions. I
wonder how many people really use it. I love it, well, I love what I
know about it. The docs seems a little hard to come by.

This is something we should change – anyone want to work on an
initially wiki-based (english) documentation of dRB with me? It’s
something I could enjoy delving deeply into, and I think that some
extensions could be useful as well.

I’d host the wiki unless someone else really cares to – I’ve a server
on a dual T-1 to offer, and a DS-3 coming in October. Bandwidth and CPU
are cheap :wink:

I think this’d be a very Good Thing, especially if it the DRB homepage
referred to it.

I’m happy to be a wikignome for it.
Cheers,
Euan
Gawnsoft: http://www.gawnsoft.co.sr
Symbian/Epoc wiki: http://html.dnsalias.net:1122
Smalltalk links (harvested from comp.lang.smalltalk) http://html.dnsalias.net/gawnsoft/smalltalk

···

On Thu, 7 Aug 2003 07:58:29 +0900, Aredridel aredridel@nbtsc.org

I scratched together some notes at:

http://www.eng.cse.dmu.ac.uk/~hgs/ruby/dRuby/

but I don’t think I got everything right. Feel free to
use this if it is of any use at all. That’s why I wrote
it somewhere visible.

I know, and I’ve been referring to it heavily. Thanks!

BTW, is the RDoc on that page really for 1.3.8? Think you could update it? I
suppose I could RDoc it myself, but I’d rather be lazy :wink:

I’ve not got into SSL with this yet, I’m using SHA1’s of
(nonce + passwd)s to authenticate messages at the moment.

Really? Can you tell me a bit more about that? Perhaps I can avoid SSL
altogether.

Nathaniel

<:((><

···

Hugh Sasse Staff Elec Eng [mailto:hgs@dmu.ac.uk] wrote:

I scratched together some notes at:

http://www.eng.cse.dmu.ac.uk/~hgs/ruby/dRuby/

I know, and I’ve been referring to it heavily. Thanks!

Thanks, nice to know it is of some use.

BTW, is the RDoc on that page really for 1.3.8? Think you could update it? I
suppose I could RDoc it myself, but I’d rather be lazy :wink:

Yes, it is for dRuby-1.3.8 [not Ruby-1.3.8! I joined the ruby
community circa 1.4.3 :-)] Thanks for the reminder, I’ll update
that.

I’ve not got into SSL with this yet, I’m using SHA1’s of
(nonce + passwd)s to authenticate messages at the moment.

Really? Can you tell me a bit more about that? Perhaps I can avoid SSL
altogether.

It doesn’t encrypt the message, but does a checksum with data that
is never transmitted. Thus you can only forge the checksum if you
have that data, so you can trust it. From the comments I wrote:

A nonce is a word that is used only once (according to concise

Oxford Dictionary.) The purpose is that it is generated, and a

password is added to it, and the hash of the whole string is

generated. Thus a hash is passed across the network so that the

password can be checked against this hash without having to send

the password across the network. This is used in CRAM-MD5, see

RFC2195 and RFC2104. CRAM == Challenge Response Authentication

Mechanism, MD5 is the message digest format. An Alternative to MD5

is SHA1.

I’d rather not post my code, because of exposing weaknesses in it.
These will exist because I find cryptographic systems full of
subtleties, one of the reasons I have not got to grips with writing
SSH code. This is slightly better, I suppose, than thinking I can
write such things and have them secure!

Nathaniel

<:((><

    Hugh
···

On Thu, 7 Aug 2003, Nathaniel Talbott wrote:

Hugh Sasse Staff Elec Eng [mailto:hgs@dmu.ac.uk] wrote:

I’m not sure why you want a nonce here; just a hash of (message + shared
secret) will do. But if you’re paranoid you’ll sign your objects with a
timestamp as well.

Try the code below. You can store session objects in a HTML input field like
this, or if the objects are small enough they can be sent to the browser as
a cookie!

Regards,

Brian.

class SecureMarshall
def initialize(secret, lifetime = 3600)
require ‘digest/md5’
unless secret.is_a? String and secret.size >= 12
raise “SecureMarshall secret must be at least 12 characters”
end
@secret = secret
@lifetime = lifetime
end

def encode(obj)
  out = Marshal.dump([obj, Time.now.to_i + @lifetime])
  [Marshal.dump([out, Digest::MD5::digest(out + @secret)])].  \
	pack("m").gsub(/\n/,'')   # base64 encode
end

def decode(key)
  raise TypeError, "Input must be a String" unless key.is_a? String
  out, hash = Marshal.load(key.unpack("m")[0])
  if Digest::MD5::digest(out + @secret) != hash
    raise ArgumentError, "Invalid signature! Tampering with objects is forbidden"
  end
  obj, expiry = Marshal.load(out)
  if Time.now.to_i > expiry
    raise "Object expired"
  end
  obj
end

def freshen(key)
  encode(decode(key))   # re-sign the object with a new lifetime
end

end

if FILE == $0
require ‘test/unit’
class MarshallTest < Test::Unit::TestCase
def setup
@crypt = SecureMarshall.new(“wibbly bibbly”, 2)
@obj = [“fred”, “jim”]
end

  def test_decode
    a = @crypt.encode(@obj)
    b = @crypt.decode(a)
    assert_equal(@obj,b)
  end

  def test_wrong_key
    a = @crypt.encode(@obj)
    crypt2 = SecureMarshall.new("another secret", 2)
    assert_raises(ArgumentError) { crypt2.decode(a) }
  end

  def test_tamper
    a = @crypt.encode(@obj)
    a[25] += 1  # in the middle of the MD5 checksum
    assert_raises(ArgumentError) { @crypt.decode(a) }
  end

  def test_lifetime
    a = @crypt.encode(@obj)
    sleep 4
    assert_raises(RuntimeError) { @crypt.decode(a) }
  end

  def test_freshen
    a = @crypt.encode(@obj)
    4.times do
      sleep 1
      a = @crypt.freshen(a)
    end
    b = @crypt.decode(a)
    assert_equal(@obj,b)
  end
end

end

···

On Thu, Aug 07, 2003 at 06:49:32PM +0900, Hugh Sasse Staff Elec Eng wrote:

It doesn’t encrypt the message, but does a checksum with data that
is never transmitted. Thus you can only forge the checksum if you
have that data, so you can trust it. From the comments I wrote:

A nonce is a word that is used only once (according to concise

Oxford Dictionary.) The purpose is that it is generated, and a

password is added to it, and the hash of the whole string is

generated. Thus a hash is passed across the network so that the

password can be checked against this hash without having to send

the password across the network.

BTW, is the RDoc on that page really for 1.3.8? Think you could update it? I
suppose I could RDoc it myself, but I’d rather be lazy :wink:

Yes, it is for dRuby-1.3.8 [not Ruby-1.3.8! I joined the ruby
community circa 1.4.3 :-)] Thanks for the reminder, I’ll update
that.

new revision: 1.12; previous revision: 1.11
enter log message, terminated with single ‘.’ or end of file:

Added rdoc docs for druby 1.3.9 and 2.0.4
.

    Hugh
···

On Thu, 7 Aug 2003, Hugh Sasse Staff Elec Eng wrote:

On Thu, 7 Aug 2003, Nathaniel Talbott wrote:

Really? Can you tell me a bit more about that? Perhaps I
can avoid SSL altogether.

It doesn’t encrypt the message, but does a checksum with data
that is never transmitted. Thus you can only forge the
checksum if you have that data, so you can trust it.

Ah… that isn’t enough for me. I want information hiding as well.

From the comments I wrote:

A nonce is a word that is used only once (according to concise

Oxford Dictionary.) The purpose is that it is generated, and a

password is added to it, and the hash of the whole string is

generated. Thus a hash is passed across the network so that the

password can be checked against this hash without having to send

the password across the network. This is used in CRAM-MD5, see

RFC2195 and RFC2104. CRAM == Challenge Response Authentication

Mechanism, MD5 is the message digest format. An Alternative to MD5

is SHA1.

I still don’t quite understand… is the nonce generated somehow? If so, how
do both sides use the same nonce?

I’d rather not post my code, because of exposing weaknesses
in it. These will exist because I find cryptographic systems
full of subtleties, one of the reasons I have not got to
grips with writing SSH code. This is slightly better, I
suppose, than thinking I can write such things and have them secure!

Security through obscurity, eh? :wink:

I can understand your sentiments. Actually, I was thinking about putting
together a ‘locked-down’ version of DRb, and submitting it for peer review.
As Bruce Schneier said (pardon the long quote),

"Security engineering is not like any other type of
engineering. An engineer who’s building something
will spend all night to make it work.
That’s quintessentially what a good hack is. It
works, it’s functional. In a normal product, it’s
what it does that’s impressive.

"But security products are not useful because of
what they do; they’re useful precisely because of
what they don’t allow to happen. Security has
nothing to do with functionality.

"If you were to build a word processor and
wanted to know if it printed, you could plug a
printer in, push the print button, and see if a
printed document came out. If you’re building a
encryption product, you can put a file in, watch
it encrypt and decrypt. You know it works, but
you have no idea if it’s secure or not. And that’s
a big deal. What it means is that you can’t tell if
a product’s secure simply by examining it, simply
by running it through functional tests.

“No amount of beta testing will find a security
flaw. In many ways, security engineering is similar
to safety engineering. But there is a difference.
Safety engineering has to do with making
something work in the presence of random or
transient faults (i.e., Murphy’s Law). Security
programming involves making sure something
works even in the presence of a malicious adversary
who will make exactly the wrong thing
fail at exactly the wrong time and do it again,
and again, and again, and again to break the security.
That’s why I call it programming Satan’s
computer. You program a computer with the assumption
that a malicious adversary intent on
defeating the system is living inside the system.
Security is supposed to provide some way to encapsulate
him.”

from “Security in the Real World: How to Evaluate Security Technology”
by Bruce Schneier
http://www.counterpane.com/real-world-security.pdf

Which scares me a bit, since it means the software I write can work great
for my users, and yet be totally insecure - and that insecurity won’t be
discovered either until it’s compromised, or until I discover it myself.

So my basic strategy at this point is to assume that user’s passwords are
insecure, and thus carefully lock down my server-side interface so that
remote users can’t do anything unsafe on the server. SSL is basically just
for information hiding, so that the data that’s being passed can’t be
trivially sniffed on the network. The data is of the type that shouldn’t be
shared, but if it were somehow decrypted, there aren’t any corporate secrets
or anything.

As for locking down the server-side interface, I’ve done a couple of things.
First of all, I’m running at $SAFE = 1, meaning that tainted strings can’t
be used for insecure operations. Second, I’ve locked down DRb such that only
methods that I specifically allow may be called, as opposed to the normal
strategy of any method except those you specifically deny (i.e. make
private). I plan to keep an eye on it as I continue, and see if there’s
anything else I need to do.

One thing I’d love to see happen is an easy to use, easy to understand, well
documented suite of ruby security libraries and tools built around the
OpenSSL library, so that security is easy(er) to set up and use. Currently
it’s tempting to do something less than secure because it’s quite complex to
get something secure going. For instance, I toyed with setting up a
certificate authority and distributing signed certificates to each client of
my app, but the documentation and tools for doing that are, at least to this
idiot, obscure, convoluted and complex. It’d be nice if Ruby emerged as a
solution for doing this simply and well. I know that there are those that
fear making these things too easy, as some will be lulled in to a false
sense of security, but I can’t see it being worse than it is now, with the
issue all too often ignored.

Anyhow, sorry for the long email. If anyone has any further ideas for how to
secure things, I’m all ears.

Nathaniel

<:((><

···

Hugh Sasse Staff Elec Eng [mailto:hgs@dmu.ac.uk] wrote:

On Thu, 7 Aug 2003, Nathaniel Talbott wrote:

I’m not sure why you want a nonce here; just a hash of (message + shared
secret) will do. But if you’re paranoid you’ll sign your objects with a
timestamp as well.

Initial authentication, and the nonce means they can’t just forge
the hashed passwd, and use that never-changing hash to authenticate
themselves. I time out the nonce, so responses which are too
late won’t be accepted.

Try the code below. You can store session objects in a HTML input field like
this, or if the objects are small enough they can be sent to the browser as
a cookie!

Regards,

Brian.

class SecureMarshall
def initialize(secret, lifetime = 3600)
require ‘digest/md5’
[…error checking…]
@secret = secret
@lifetime = lifetime
end

def encode(obj)
  out = Marshal.dump([obj, Time.now.to_i + @lifetime])
  [Marshal.dump([out, Digest::MD5::digest(out + @secret)])].  \
  pack("m").gsub(/\n/,'')   # base64 encode
end
    [...]

This only works on one machine, and leaves the secret lying around
in memory (@secret). You can’t really pass this object over the net
without exposing the secret. This is the sort of subtlety that
catches me out every time!

    Hugh
···

On Thu, 7 Aug 2003, Brian Candler wrote:

It doesn’t encrypt the message, but does a checksum with data

Ah… that isn’t enough for me. I want information hiding as well.

From the comments I wrote:

I still don’t quite understand… is the nonce generated somehow? If so, how
do both sides use the same nonce?

Server generates nonce (as a function of whatever. ($$, time, current
England cricket score, or something)).
Client sees nonce (world sees nonce, too)
Client sticks passwd on the end of nonce, and hashes the whole thing.
Client sends hash back to server.
Server sees response from client, and reconstructs the hash in the
same way as the client. If they agree all is OK.
The hash function makes it hard for Eve to guess the passwd, and
impossible to directly calculate it because information is
destroyed.

I’d rather not post my code, because of exposing weaknesses
in it. These will exist because I find cryptographic systems
full of subtleties, one of the reasons I have not got to
grips with writing SSH code. This is slightly better, I
suppose, than thinking I can write such things and have them secure!

Security through obscurity, eh? :wink:

Well, not entirely. I know that obscurity on its own is rubbish.
It’s more like not advertising that you use a lock which others know
to be weak. The obscurity is not better than thinking I can invent
crypto systems. The avoidance of encryption is better than such
naivety. I think. And I could be wrong; there always seems to be one
more level of subtlety. But there are areas where the data cannot be sent
in plain sight, so this is not universally applicable.

I can understand your sentiments. Actually, I was thinking about putting
together a ‘locked-down’ version of DRb, and submitting it for peer review.
As Bruce Schneier said (pardon the long quote),
"[…]
it encrypt and decrypt. You know it works, but
you have no idea if it’s secure or not. And that’s
a big deal. What it means is that you can’t tell if
[…]
transient faults (i.e., Murphy’s Law). Security
programming involves making sure something
works even in the presence of a malicious adversary
who will make exactly the wrong thing
fail at exactly the wrong time and do it again,
and again, and again, and again to break the security.

And HOW do you test (first) for this? :slight_smile:

    [...]"

by Bruce Schneier
http://www.counterpane.com/real-world-security.pdf

Which scares me a bit, since it means the software I write can work great
for my users, and yet be totally insecure - and that insecurity won’t be
discovered either until it’s compromised, or until I discover it myself.

Exactly.

One thing I’d love to see happen is an easy to use, easy to understand, well
documented suite of ruby security libraries and tools built around the
OpenSSL library, so that security is easy(er) to set up and use. Currently

Yes. There are still subtleties, though…
[…]

my app, but the documentation and tools for doing that are, at least to this
idiot, obscure, convoluted and complex. It’d be nice if Ruby emerged as a
solution for doing this simply and well. I know that there are those that
fear making these things too easy, as some will be lulled in to a false
sense of security, but I can’t see it being worse than it is now, with the
issue all too often ignored.

And there are plenty of governments who object to people being able
to provide security as well. This just adds to the complexity. Yet
another reason why I tried to work without actual cryptography.

Anyhow, sorry for the long email. If anyone has any further ideas
for how to secure things, I’m all ears.

Nathaniel

<:((><

    Hugh
···

On Thu, 7 Aug 2003, Nathaniel Talbott wrote:

Hugh Sasse Staff Elec Eng [mailto:hgs@dmu.ac.uk] wrote:

I think you may have misunderstood the purpose of this class.

If you are working across two machines, you instantiate a separate copy of
SecureMarshall (with the same shared secret) on each one. You use it to
encode objects, which you squirt across the network, and decode at the other
end. The SecureMarshall object itself is not sent across the network!

If decode() accepts the object, it proves it was signed by the sender (i.e.
someone who knew the shared secret).

Sure the secret is in memory in @secret. You can’t avoid that - well, you
can read it off disk each time you use it instead, but that’s no more
secure; in fact you will leave lots of objects in memory which contain the
secret, until the garbage collector picks them up.

Regards,

Brian.

···

On Thu, Aug 07, 2003 at 07:58:59PM +0900, Hugh Sasse Staff Elec Eng wrote:

class SecureMarshall
def initialize(secret, lifetime = 3600)
require ‘digest/md5’
[…error checking…]
@secret = secret
@lifetime = lifetime
end

def encode(obj)
  out = Marshal.dump([obj, Time.now.to_i + @lifetime])
  [Marshal.dump([out, Digest::MD5::digest(out + @secret)])].  \
  pack("m").gsub(/\n/,'')   # base64 encode
end
    [...]

This only works on one machine, and leaves the secret lying around
in memory (@secret). You can’t really pass this object over the net
without exposing the secret. This is the sort of subtlety that
catches me out every time!

OK. That lets B authenticate A. The main weakness is that if the nonce and
response are sniffed, the password is subject to an off-line dictionary
attack.

And of course, this exchange does not protect the rest of the data in
transit. An active attacker could allow this authentication exchange to take
place, and then substitute the subsequent session data with something else.

Regards,

Brian.

···

On Fri, Aug 08, 2003 at 12:03:01AM +0900, Hugh Sasse Staff Elec Eng wrote:

Server generates nonce (as a function of whatever. ($$, time, current
England cricket score, or something)).
Client sees nonce (world sees nonce, too)
Client sticks passwd on the end of nonce, and hashes the whole thing.
Client sends hash back to server.
Server sees response from client, and reconstructs the hash in the
same way as the client. If they agree all is OK.
The hash function makes it hard for Eve to guess the passwd, and
impossible to directly calculate it because information is
destroyed.