[Haskell-cafe] ANNOUNCE: tls, native TLS/SSL protocol implementation

Hi haskellers, I'ld like to announce the tls package [1][2], which is a native implementation of the TLS protocol, client and server. It's currently mostly supporting SSL3, TLS1.0 and TLS1.1. It's got *lots* of rough edges, and a bunch of unsupported features, but it's humming along, and at each iteration it's becoming more tighly secure and featureful. I would recommend against using this implementation in a production system just yet, or in an aggressive environment either (specially for the server side); I don't think it should necessary fail, but it's still an early implementation with probable API changes on the way. [1] http://github.com/vincenthz/hs-tls [2] http://hackage.haskell.org/package/tls -- Vincent Hanquez

On 6 October 2010 23:26, Vincent Hanquez
I'ld like to announce the tls package [1][2], which is a native implementation of the TLS protocol, client and server. It's currently mostly supporting SSL3, TLS1.0 and TLS1.1. It's got *lots* of rough edges, and a bunch of unsupported features, but it's humming along, and at each iteration it's becoming more tighly secure and featureful.
Wow, great! So might we be able to combine this with Network.HTTP some day? I am interested in moving away from C libraries (curl) to pure Haskell libraries, for a safer, richer Haskell ecosystem and for solving the interesting problems. Will you eventually add benchmarks? Reading this source code will be educational. Thanks.

On Thu, Oct 7, 2010 at 12:29 AM, Christopher Done
On 6 October 2010 23:26, Vincent Hanquez
wrote: I'ld like to announce the tls package [1][2], which is a native implementation of the TLS protocol, client and server. It's currently mostly supporting SSL3, TLS1.0 and TLS1.1. It's got *lots* of rough edges, and a bunch of unsupported features, but it's humming along, and at each iteration it's becoming more tighly secure and featureful.
Wow, great! So might we be able to combine this with Network.HTTP some day? I am interested in moving away from C libraries (curl) to pure Haskell libraries, for a safer, richer Haskell ecosystem and for solving the interesting problems.
Will you eventually add benchmarks?
Reading this source code will be educational. Thanks.
The http-enumerator package[1] actually uses either the tls package or OpenSSL as its backend. [1] http://hackage.haskell.org/package/http-enumerator

On Thu, Oct 07, 2010 at 12:29:51AM +0200, Christopher Done wrote:
On 6 October 2010 23:26, Vincent Hanquez
wrote: I'ld like to announce the tls package [1][2], which is a native implementation of the TLS protocol, client and server. It's currently mostly supporting SSL3, TLS1.0 and TLS1.1. It's got *lots* of rough edges, and a bunch of unsupported features, but it's humming along, and at each iteration it's becoming more tighly secure and featureful.
Wow, great! So might we be able to combine this with Network.HTTP some day? I am interested in moving away from C libraries (curl) to pure Haskell libraries, for a safer, richer Haskell ecosystem and for solving the interesting problems.
That's one of the goal of this library. Ultimately I want something more flexible than usual APIs in traditional libraries; TLS can do lots of things, that are not typically exposed by others libraries. Otherwise more pratically, there's michael's http-enumerator. I hope i'll see more package depending on tls in the future instead of gnutls/openssl bindings.
Will you eventually add benchmarks?
This is on my TODO list but the priority is quite low; I'm trying to focus on correctness and security for now. However I suspect what does make the biggest difference is the crypto implementation that is used, and the current dependencies should be all reasonable (cryptohash is close to C performance level with hashes, the AES package has a pretty fast implementation, ghc seems quite good with big number benefiting RSA, ..). -- Vincent Hnquez

Does native mean "Haskell only" - without FFI? -- Regards, Kashyap

On 8 October 2010 07:44, C K Kashyap
Does native mean "Haskell only" - without FFI?
I think "not Haskell" would be piping to a separate non-Haskell process or calling by FFI to another language to do the interesting work. Thus "native" is not using these for the interesting work. E.g. I can call out to zlib with the FFI and call it a Haskell zlib library. It's not really a native Haskell implementation, though.

On Fri, Oct 8, 2010 at 8:08 AM, Christopher Done
On 8 October 2010 07:44, C K Kashyap
wrote: Does native mean "Haskell only" - without FFI?
I think "not Haskell" would be piping to a separate non-Haskell process or calling by FFI to another language to do the interesting work. Thus "native" is not using these for the interesting work. E.g. I can call out to zlib with the FFI and call it a Haskell zlib library. It's not really a native Haskell implementation, though.
By the way, a native zlib implementation would definitely go on my wishlist. Any takers? ;) Michael

On Fri, Oct 08, 2010 at 08:47:39AM +0200, Michael Snoyman wrote:
By the way, a native zlib implementation would definitely go on my wishlist. Any takers? ;)
Me too ! that's the only thing that prevented me from adding the compression layer to TLS. as such it's on my todo list, but really really low priority ;) -- Vincent

On Fri, Oct 8, 2010 at 10:26 AM, Vincent Hanquez
On Fri, Oct 08, 2010 at 08:47:39AM +0200, Michael Snoyman wrote:
By the way, a native zlib implementation would definitely go on my wishlist. Any takers? ;)
Me too ! that's the only thing that prevented me from adding the compression layer to TLS. as such it's on my todo list, but really really low priority ;)
Well, it's not a native (= pure Haskell) implementation, but I just released zlib-bindings[1] the provides a more Haskell-ish interface than the raw C API of zlib, yet a more low-level and stream-oriented API than the zlib package. I've put up a little blog post explaining the package a bit[2]. Michael [1] http://hackage.haskell.org/package/zlib-bindings [2] http://docs.yesodweb.com/blog/announcing-zlib-bindings/

On Fri, Oct 08, 2010 at 11:14:01AM +0530, C K Kashyap wrote:
Does native mean "Haskell only" - without FFI?
Native means the implementation is in haskell, and the library is not using another implementation (in another language) to do the work: either through FFI as a binding, or as a wrapper to an external program. -- Vincent Hanquez

Vincent Hanquez wrote:
On Fri, Oct 08, 2010 at 11:14:01AM +0530, C K Kashyap wrote:
Does native mean "Haskell only" - without FFI?
Native means the implementation is in haskell, and the library is not using another implementation (in another language) to do the work: either through FFI as a binding, or as a wrapper to an external program.
What's the motivation for this? One thing I can see is that it would make things easier to install on Windows. Ganesh =============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html ===============================================================================

On 8 October 2010 13:54, Sittampalam, Ganesh
Vincent Hanquez wrote:
On Fri, Oct 08, 2010 at 11:14:01AM +0530, C K Kashyap wrote:
Does native mean "Haskell only" - without FFI?
Native means the implementation is in haskell, and the library is not using another implementation (in another language) to do the work: either through FFI as a binding, or as a wrapper to an external program.
What's the motivation for this?
One thing I can see is that it would make things easier to install on Windows.
Indeed. Easier to install, easier to hack on (for Haskellers). Haskell program coverage, debugging, extending your quickcheck tests, etc.

On Fri, Oct 08, 2010 at 02:08:29PM +0200, Christopher Done wrote:
Indeed. Easier to install, easier to hack on (for Haskellers). Haskell program coverage, debugging, extending your quickcheck tests, etc.
absolutely. I'm certainly hoping to quickcheck all that is quickcheckable. The next thing i want to add to the tests is the TLS startup configuration, to that quickcheck test every possible handshake scenario (certificate, no certificate, block cipher, stream cipher, RSA, DH, DSA, TLS1.2, TLS1.1, TLS1.0, SSL3, etc). There's also the type-system experience, which raise the safety experience massively. I feel much better seeing pure functions and clearly bounded types instead of a pointer to the whole world as it is quite common in gnutls and openssl. -- Vincent

On Fri, Oct 08, 2010 at 12:54:48PM +0100, Sittampalam, Ganesh wrote:
What's the motivation for this?
Well, I wanted to have a tls/ssl module that integrate nicely with haskell. until then the 2 solutions were: - shelling out to curl: that's not great, usually works until you have an error, and then you're greeted with a curl command line error. the control is pretty poor, what if you want a fancy certificate control ? Also you have absolutely no server support in this case, this is client only. - using either gnutls or openssl bindings: there's multiples reasons this is not great. depending on huge C libraries (security wise, platform wise), massive usage of IO even in place where it shouldn't, low hacking potential (adding ciphers/hash, etc). Apart from that, we all know here why programming in haskell is better than doing the same thing in says, C or python. I think it apply even more when the focus of this is a secure library. -- Vincent

Vincent Hanquez wrote:
On Fri, Oct 08, 2010 at 12:54:48PM +0100, Sittampalam, Ganesh wrote:
What's the motivation for this?
Well, I wanted to have a tls/ssl module that integrate nicely with haskell. until then the 2 solutions were:
- shelling out to curl: that's not great, usually works until you have an error, and then you're greeted with a curl command line error. the control is pretty poor, what if you want a fancy certificate control ? Also you have absolutely no server support in this case, this is client only.
- using either gnutls or openssl bindings: there's multiples reasons this is not great. depending on huge C libraries (security wise, platform wise), massive usage of IO even in place where it shouldn't, low hacking potential (adding ciphers/hash, etc).
Apart from that, we all know here why programming in haskell is better than doing the same thing in says, C or python. I think it apply even more when the focus of this is a secure library.
While I agree with the potential benefits, I also worry that you will end up making something that is far less well tested in practice. For widely used and fairly low-level libraries like gnutls, openssl and zlib, I'm just skeptical that the benefits outweigh the risks and costs. Anyway, it's just a feeling. Please do prove me wrong :-) Cheers, Ganesh =============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html ===============================================================================

While I agree with the potential benefits, I also worry that you will end up making something that is far less well tested in practice. For widely used and fairly low-level libraries like gnutls, openssl and zlib, I'm just skeptical that the benefits outweigh the risks and costs.
Anyway, it's just a feeling. Please do prove me wrong :-)
This certainly isn't a proof by a long shot, but my feeling on at least low-level libraries is exactly the reverse of this. C libraries are usually designed to be extremely stateful (this certainly includes openssl), and because of that any Haskell wrapper for them ends up being heavily IO based. The result of this is that any code that incorporates it ends up being trapped in an IO mess to do essentially pure (yes, I know the arguments about IO being pure, you know what I mean) things. It's precisely these libraries that we need not just implemented in a "native" way, but designed in a pure, beautiful, simple way for Haskell. While I can see your point about potentially introducing new security holes, and producing much less trusted code, I feel having tidy, pure libraries that we can all integrate into our Haskell is a benefit that far outweighs this. Especially when we have nice things like the type system, which can be used to alleviate many of the security worries. Tom Davie

On Mon, Oct 11, 2010 at 09:06:45AM +0100, Sittampalam, Ganesh wrote:
While I agree with the potential benefits, I also worry that you will end up making something that is far less well tested in practice. For widely used and fairly low-level libraries like gnutls, openssl and zlib, I'm just skeptical that the benefits outweigh the risks and costs.
Hi Ganesh, You're absolutely right in the fact there's risk involved. Cryptography related things are hard to get right, I won't be denying it. However I'm really not a big fan of the alternative. Having to rely forever on blessed black boxes coded in low level languages, doesn't sound appealing to me. There's the risk that cryptography becomes even more voodoo magic by doing that. This is certainly true for TLS/SSL. a lots of people have no idea how it works, what it does and doesn't do. So hopefully having a clean haskell library will make more people interested, in changing this black-box state; an even bigger hope, is to vulgarize cryptography, instead of making it more opaque ;)
Anyway, it's just a feeling. Please do prove me wrong :-)
I'll certainly try ;) -- Vincent

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 10/11/10 04:06 , Sittampalam, Ganesh wrote:
While I agree with the potential benefits, I also worry that you will end up making something that is far less well tested in practice. For widely used and fairly low-level libraries like gnutls, openssl and zlib, I'm just skeptical that the benefits outweigh the risks and costs.
I see your point, but I would be prepared to trust a clean, typesafe (and especially if it's pure) Haskell implementation over the Cthulhu's-tentacles that is openssl. :) - -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAky0VikACgkQIn7hlCsL25Wt/QCgneAyuCttwnyrHG4vuC22sNBp Y7gAnAtKUoNekXUb61ISYwnmSkZWJejM =3+oI -----END PGP SIGNATURE-----

* Vincent Hanquez:
Native means the implementation is in haskell, and the library is not using another implementation (in another language) to do the work: either through FFI as a binding, or as a wrapper to an external program.
I can see how this terminology makes sense, but it's the opposite of the usage in Java (where "native" == "unmanaged code called via JNI").

On Fri, Oct 8, 2010 at 3:36 PM, Florian Weimer
* Vincent Hanquez:
Native means the implementation is in haskell, and the library is not using another implementation (in another language) to do the work: either through FFI as a binding, or as a wrapper to an external program.
I can see how this terminology makes sense, but it's the opposite of the usage in Java (where "native" == "unmanaged code called via JNI").
I guess it depends on the context. If the context is a C program then 'native' means the C code in the program and 'foreign' means other code like Haskell. If the context is a Haskell program then 'native' means the Haskell code and 'foreign' means other code like C. Most of the time we're programming in Haskell so I think our context is Haskell. Also note that the "_Foreign_ Function Interface" hasn't been named the "Haskell _Native_ Interface". Bas

Quoth Bas van Dijk
On Fri, Oct 8, 2010 at 3:36 PM, Florian Weimer
wrote: ... I can see how this terminology makes sense, but it's the opposite of the usage in Java (where "native" == "unmanaged code called via JNI").
I guess it depends on the context. If the context is a C program then 'native' means the C code in the program and 'foreign' means other code like Haskell. If the context is a Haskell program then 'native' means the Haskell code and 'foreign' means other code like C.
wikipedia: "Managed code is a differentiation coined by Microsoft to identify computer program code that requires and will only execute under the "management" of a Common Language Runtime virtual machine (resulting in Bytecode)." In other words, a new way to say `interpreted', and `native' vs. `interpreted' is a familiar distinction for more computing environments than just Java. But it isn't relevant here, right? Since neither the Haskell nor OpenSSL implementations are both compiled to CPU instructions. Donn Cave, donn@avvanta.com

* Donn Cave:
wikipedia: "Managed code is a differentiation coined by Microsoft to identify computer program code that requires and will only execute under the "management" of a Common Language Runtime virtual machine (resulting in Bytecode)."
I like this term, I apply it by extension to any system which enforces memory safety (as long as you stick to non-internals, such as array indexing, even Java has got (in practical terms) fairly portable PEEK/POKE operations).
In other words, a new way to say `interpreted',
This term doesn't really apply that well to the CLR because its bytecode really can't be interpreted efficiently. (The bytecodes lack type information.)
and `native' vs. `interpreted' is a familiar distinction for more computing environments than just Java. But it isn't relevant here, right? Since neither the Haskell nor OpenSSL implementations are both compiled to CPU instructions.
Obviously, this depends on the implementation. For Haskell and Java, implementations which are based on precompiled machine code exist. There are also implementations which rely on some form of interpretation exclusively. That's why the managed/unmanaged distinction is more useful than the interpreted/compiled distinction.

Quoth Florian Weimer
wikipedia: "Managed code is a differentiation coined by Microsoft to identify computer program code that requires and will only execute under the "management" of a Common Language Runtime virtual machine (resulting in Bytecode)."
I like this term, I apply it by extension to any system which enforces memory safety (as long as you stick to non-internals, such as array indexing, even Java has got (in practical terms) fairly portable PEEK/POKE operations).
... enforces memory safety? Can't that be done in code compiled straight to CPU instructions without even calling a run-time, let alone being managed by one? I'm not sure what you mean, but in this case, the term has surely been extended too far - it doesn't seem to be managed code in the sense quoted above, nor does it seem to fit with common non-technical usage of "managed".
In other words, a new way to say `interpreted',
This term doesn't really apply that well to the CLR because its bytecode really can't be interpreted efficiently. (The bytecodes lack type information.)
To me, the CLR takes bytecode, maps it in some way to CPU machine code and executes the latter. I would call that "interpreted", but you wouldn't? Or am I wrong about what's happening? I know Wikipedia isn't necessarily the ultimate authority of computer science, but "Many interpreted languages are first compiled to some form of virtual machine code, which is then either interpreted or compiled at runtime to native code." (... going on to cite Java and .NET Framework among others), so I'm not the only one who finds it expedient to use that word "interpreted" in this context.
and `native' vs. `interpreted' is a familiar distinction for more computing environments than just Java. But it isn't relevant here, right? Since neither the Haskell nor OpenSSL implementations are both compiled to CPU instructions.
Obviously, this depends on the implementation. For Haskell and Java, implementations which are based on precompiled machine code exist. There are also implementations which rely on some form of interpretation exclusively. That's why the managed/unmanaged distinction is more useful than the interpreted/compiled distinction.
I don't know, of course this is partly due just to my own ignorance, but it seems to me that the awkward semantics around this distinction make it somewhat prone to confusion. Maybe the kind of thing that's useful to your understanding of computational environments, but less useful when discussing them with others? At this point, I still don't know for sure if you think a GHC-compiled Haskell program is managed, or unmanaged, but I think managed? And in my confused present state I would say it's unmanaged. Donn Cave, donn@avvanta.com

* Donn Cave:
Quoth Florian Weimer
, wikipedia: "Managed code is a differentiation coined by Microsoft to identify computer program code that requires and will only execute under the "management" of a Common Language Runtime virtual machine (resulting in Bytecode)."
I like this term, I apply it by extension to any system which enforces memory safety (as long as you stick to non-internals, such as array indexing, even Java has got (in practical terms) fairly portable PEEK/POKE operations).
... enforces memory safety? Can't that be done in code compiled straight to CPU instructions without even calling a run-time, let alone being managed by one?
It is quite possible to have memory-unsafe interpreted languages. I wouldn't necessary call them "managed". For example, a simple interpreted Forth might have explicit words for heap allocation and deallocation. This isn't a interpreted/compiled distinction (and the line between the two is increasingly blurred because there are high-performance compilers these days for languages which are traditionally considered interpreted). You need restrictions on memory deallocation (which must follow a stack or region descipline), and thus indirectly on allocation. I don't think region inference has caught on, which suggests that there are inherent limitations when trying to apply it to application code.
I'm not sure what you mean, but in this case, the term has surely been extended too far - it doesn't seem to be managed code in the sense quoted above, nor does it seem to fit with common non-technical usage of "managed".
Not really---many C programmers associate memory safety with micromanagement by the language environment.
In other words, a new way to say `interpreted',
This term doesn't really apply that well to the CLR because its bytecode really can't be interpreted efficiently. (The bytecodes lack type information.)
To me, the CLR takes bytecode, maps it in some way to CPU machine code and executes the latter. I would call that "interpreted", but you wouldn't? Or am I wrong about what's happening? I know Wikipedia isn't necessarily the ultimate authority of computer science, but "Many interpreted languages are first compiled to some form of virtual machine code, which is then either interpreted or compiled at runtime to native code." (... going on to cite Java and .NET Framework among others), so I'm not the only one who finds it expedient to use that word "interpreted" in this context.
I think the word is increasingply meaningless. Current x86 CPUs (excluding the low-power variants) turn transform the instruction stream before execution, too. Your VM hypervisor might emulate the effect of certain instruction sequences which cannot be virtualized solely in hardware. C language environments contain run-time code generation to tune for the specific CPU on which they are running. And historically, even C was compiled to bytecode, so that large programs could fit into available RAM. And so on.
At this point, I still don't know for sure if you think a GHC-compiled Haskell program is managed, or unmanaged, but I think managed?
Yupp, it's managed (at least according to my own use of the word). Haskell tries quite hard to protect its own abstractions (which is essentially another view on memory safety).
And in my confused present state I would say it's unmanaged.
Johan Tibell speaks of the "GHC I/O manager", so I think I'm in good company.

On 8 Oct 2010, at 16:56, Donn Cave wrote:
wikipedia: "Managed code is a differentiation coined by Microsoft to identify computer program code that requires and will only execute under the "management" of a Common Language Runtime virtual machine (resulting in Bytecode)."
In other words, a new way to say `interpreted',
I believe the wikipedia description is misleading. The difference between "managed" and "unmanaged" code is that the former is garbage- collected (i.e. free of memory freeing errors), whilst the latter is responsible for its own memory behaviour. Regards, Malcolm

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 10/9/10 09:17 , Malcolm Wallace wrote:
On 8 Oct 2010, at 16:56, Donn Cave wrote:
wikipedia: "Managed code is a differentiation coined by Microsoft to identify computer program code that requires and will only execute under the "management" of a Common Language Runtime virtual machine (resulting in Bytecode)."
In other words, a new way to say `interpreted',
I believe the wikipedia description is misleading. The difference between "managed" and "unmanaged" code is that the former is garbage-collected (i.e. free of memory freeing errors), whilst the latter is responsible for its own memory behaviour.
More to the point, the runtime makes it impossible to acquire a pointer to memory that is not checked. This is in specific distinction to C and C++, where the former is entirely unmanaged and the latter usually only checks pointers when compiling for debugging (and even then it's mostly just like C, only it has some assert()s in some STL constructors). - -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkywxzEACgkQIn7hlCsL25WxBgCgvvfrsSEuOk2Qaa7CUGE53K7L hxIAnjDk/N8/aJaotZN+NnGUjnCuPGqX =FwAF -----END PGP SIGNATURE-----

On Wed, 2010-10-06 at 22:26 +0100, Vincent Hanquez wrote:
Hi haskellers,
I'ld like to announce the tls package [1][2], which is a native implementation of the TLS protocol, client and server. It's currently mostly supporting SSL3, TLS1.0 and TLS1.1. It's got *lots* of rough edges, and a bunch of unsupported features, but it's humming along, and at each iteration it's becoming more tighly secure and featureful.
I would recommend against using this implementation in a production system just yet, or in an aggressive environment either (specially for the server side); I don't think it should necessary fail, but it's still an early implementation with probable API changes on the way.
[1] http://github.com/vincenthz/hs-tls [2] http://hackage.haskell.org/package/tls
1. Could also callback in addition to handles be added? Like: connect' :: (ByteString -> IO ()) -> IO ByteString -> TLSClient IO () Why: - It allows to wrap it into Enumerators 2. Does listen corresponds to listen(2)? If yes how to handle STARTTLS server-side? If no - please rename it. Regards

On Fri, Oct 8, 2010 at 1:59 PM, Maciej Piechotka
On Wed, 2010-10-06 at 22:26 +0100, Vincent Hanquez wrote:
Hi haskellers,
I'ld like to announce the tls package [1][2], which is a native implementation of the TLS protocol, client and server. It's currently mostly supporting SSL3, TLS1.0 and TLS1.1. It's got *lots* of rough edges, and a bunch of unsupported features, but it's humming along, and at each iteration it's becoming more tighly secure and featureful.
I would recommend against using this implementation in a production system just yet, or in an aggressive environment either (specially for the server side); I don't think it should necessary fail, but it's still an early implementation with probable API changes on the way.
[1] http://github.com/vincenthz/hs-tls [2] http://hackage.haskell.org/package/tls
1. Could also callback in addition to handles be added? Like:
connect' :: (ByteString -> IO ()) -> IO ByteString -> TLSClient IO ()
Why: - It allows to wrap it into Enumerators
It's entirely possible to wrap the current interface into enumerators/iteratees[1]. That's how http-enumerator works. Michael [1] http://github.com/snoyberg/http-enumerator/blob/master/Network/TLS/Client/En...

On Fri, 2010-10-08 at 15:14 +0200, Michael Snoyman wrote:
On Fri, Oct 8, 2010 at 1:59 PM, Maciej Piechotka
wrote: On Wed, 2010-10-06 at 22:26 +0100, Vincent Hanquez wrote:
Hi haskellers,
I'ld like to announce the tls package [1][2], which is a native implementation of the TLS protocol, client and server. It's currently mostly supporting SSL3, TLS1.0 and TLS1.1. It's got *lots* of rough edges, and a bunch of unsupported features, but it's humming along, and at each iteration it's becoming more tighly secure and featureful.
I would recommend against using this implementation in a production system just yet, or in an aggressive environment either (specially for the server side); I don't think it should necessary fail, but it's still an early implementation with probable API changes on the way.
[1] http://github.com/vincenthz/hs-tls [2] http://hackage.haskell.org/package/tls
1. Could also callback in addition to handles be added? Like:
connect' :: (ByteString -> IO ()) -> IO ByteString -> TLSClient IO ()
Why: - It allows to wrap it into Enumerators
It's entirely possible to wrap the current interface into enumerators/iteratees[1]. That's how http-enumerator works.
Michael
[1] http://github.com/snoyberg/http-enumerator/blob/master/Network/TLS/Client/En...
I had in mind something like: import Data.ByteString import Data.Iteratee clientEnum :: MonadIO m => params -> Enumerator ByteString m a -> Enumerator ByteString m a clientEnum params client = ... i.e. clientEnum :: MonadIO m => params -> (Iteratee ByteString m a -> m (Iteratee ByteString m a)) -- ^ Client function -> Iteratee ByteString m a --^ "Output" -> m (Iteratee ByteString m a) --^ "Input" Where inner enumerator is simply a client side while 'outer' is a outside/server part. Regards

On Fri, Oct 8, 2010 at 3:29 PM, Maciej Piechotka
I had in mind something like:
import Data.ByteString import Data.Iteratee
clientEnum :: MonadIO m => params -> Enumerator ByteString m a -> Enumerator ByteString m a clientEnum params client = ...
i.e.
clientEnum :: MonadIO m => params -> (Iteratee ByteString m a -> m (Iteratee ByteString m a)) -- ^ Client function -> Iteratee ByteString m a --^ "Output" -> m (Iteratee ByteString m a) --^ "Input"
Where inner enumerator is simply a client side while 'outer' is a outside/server part.
Regards
I'm afraid I haven't really looked at iteratee 0.4 enough to understand those type signatures completely, but it looks pretty similar to the API I have. Am I missing something? And is there a reason you can't implement that against the current tls API? Michael

On 10/10/10, Michael Snoyman
On Fri, Oct 8, 2010 at 3:29 PM, Maciej Piechotka
wrote: I had in mind something like:
import Data.ByteString import Data.Iteratee
clientEnum :: MonadIO m => params -> Enumerator ByteString m a -> Enumerator ByteString m a clientEnum params client = ...
i.e.
clientEnum :: MonadIO m => params -> (Iteratee ByteString m a -> m (Iteratee ByteString m a)) -- ^ Client function -> Iteratee ByteString m a --^ "Output" -> m (Iteratee ByteString m a) --^ "Input"
Where inner enumerator is simply a client side while 'outer' is a outside/server part.
Regards
I'm afraid I haven't really looked at iteratee 0.4 enough to understand those type signatures completely, but it looks pretty similar to the API I have. Am I missing something? And is there a reason you can't implement that against the current tls API?
Michael
Yes as far as I understend. My signature is parametrized both in client side of protocol as well as "native". I.e. in my signature you don't need to have any Handle but the encrypted output is simply passed to next iteratee. Regards

On Sun, Oct 10, 2010 at 3:09 PM, Maciej Piechotka
On 10/10/10, Michael Snoyman
wrote: On Fri, Oct 8, 2010 at 3:29 PM, Maciej Piechotka
wrote: I had in mind something like:
import Data.ByteString import Data.Iteratee
clientEnum :: MonadIO m => params -> Enumerator ByteString m a -> Enumerator ByteString m a clientEnum params client = ...
i.e.
clientEnum :: MonadIO m => params -> (Iteratee ByteString m a -> m (Iteratee ByteString m a)) -- ^ Client function -> Iteratee ByteString m a --^ "Output" -> m (Iteratee ByteString m a) --^ "Input"
Where inner enumerator is simply a client side while 'outer' is a outside/server part.
Regards
I'm afraid I haven't really looked at iteratee 0.4 enough to understand those type signatures completely, but it looks pretty similar to the API I have. Am I missing something? And is there a reason you can't implement that against the current tls API?
Michael
Yes as far as I understend. My signature is parametrized both in client side of protocol as well as "native". I.e. in my signature you don't need to have any Handle but the encrypted output is simply passed to next iteratee.
Sorry, I see what you're saying now. Yes, that would indeed be a nice feature, though not one I needed for http-enumerator. Michael

On Fri, Oct 08, 2010 at 12:59:56PM +0100, Maciej Piechotka wrote:
1. Could also callback in addition to handles be added? Like:
connect' :: (ByteString -> IO ()) -> IO ByteString -> TLSClient IO ()
Would an interface that generate the packet to send and just return them as bytes be even better ? connect' :: TLSClient () ByteString I'm hoping to have something like that so i can use quickcheck to verify that all possible configurations result in a workable connection.
2. Does listen corresponds to listen(2)? If yes how to handle STARTTLS server-side? If no - please rename it.
it's not doing the same thing as the socket listen(2). it waits for the handle passed as argument to establish a new TLS session as in: listen to the new tls connection. after reading STARTTLS, you would call listen that would listen for the TLS context to be established. Please suggest something, if you want me to rename it though, as I can't really think of a better name. -- Vincent Hanquez

On Sat, 2010-10-09 at 09:27 +0100, Vincent Hanquez wrote:
On Fri, Oct 08, 2010 at 12:59:56PM +0100, Maciej Piechotka wrote:
1. Could also callback in addition to handles be added? Like:
connect' :: (ByteString -> IO ()) -> IO ByteString -> TLSClient IO ()
Would an interface that generate the packet to send and just return them as bytes be even better ?
connect' :: TLSClient () ByteString
I'm hoping to have something like that so i can use quickcheck to verify that all possible configurations result in a workable connection.
I don't think I quite follow. Could you explain?
2. Does listen corresponds to listen(2)? If yes how to handle STARTTLS server-side? If no - please rename it.
it's not doing the same thing as the socket listen(2).
it waits for the handle passed as argument to establish a new TLS session as in: listen to the new tls connection.
after reading STARTTLS, you would call listen that would listen for the TLS context to be established.
Please suggest something, if you want me to rename it though, as I can't really think of a better name.
Maybe serverStartTLS? Regards

On Sat, Oct 09, 2010 at 12:53:17PM +0100, Maciej Piechotka wrote:
I don't think I quite follow. Could you explain?
sorry for beeing confusing. I meant something like a pure iteratee interface, so that you get the marshalled data to send in a bytestring format, and then you can decide yourself what to do with this bytestring (send it to a handle, discard it, process it as the other side)
Maybe serverStartTLS?
ok, I'll think about it; I'm not thrilled by that though ;) -- Vincent
participants (12)
-
Bas van Dijk
-
Brandon S Allbery KF8NH
-
C K Kashyap
-
Christopher Done
-
Donn Cave
-
Florian Weimer
-
Maciej Piechotka
-
Malcolm Wallace
-
Michael Snoyman
-
Sittampalam, Ganesh
-
Thomas Davie
-
Vincent Hanquez