Error in BIO_should_retry man page
I'm wondering if there's an error in the man page of BIO_should_retry. Under description, it says: "BIO_get_retry_reason() returns a mask of the cause of a retry condition consisting of the values BIO_FLAGS_READ, BIO_FLAGS_WRITE, BIO_FLAGS_IO_SPECIAL though current BIO types will only set one of these." I think it should read like this: "BIO_retry_type() returns a mask ..." Further down it says: "BIO_get_retry_reason() returns the reason for a special condition..." I guess the later definition is the correct definition of BIO_get_retry_reason(). I would appreciate if someone could look into this and let me know their opinion. Thanks Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: post-connection assertions
Dave Thompson wrote: 3. Use SSL_set_verify() and provide a callback function. This sounds promising but the callback function gets called for every certificate in the chain. How can I find out whether the certificate in question is the peer's cert and not some intermediate cert? x509storectx->error_depth == 0 (1,2,... are the CAs) even though this callback isn't for error. Yeah, it looks silly but it works. Look at the loop in x509/x509_vfy.c internal_verify() to see why. That works fine. Thanks a lot. -Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
post-connection assertions
I'm wondering what's the best way to check the identity of the peer i.e. compare the commonName or subjectAltName included in the x509 cert with the data I expect. The book "Network Security with OpenSSL" calls this "Post-connection assertions" (page 134). I already managed to extract all that data from the x509 certificate so that's not the issue. So I call SSL_get_verify_result() and SSL_get_peer_certificate(). My question is *when* to call these functions. Some alternatives come into my mind. But I do not like any of them: 1. Call those functions when SSL_accept() (or SSL_connect()) returns success. That's not an option for me cos I want to use the implicit connection setup provided by SSL_read() and SSL_write() 2. Use SSL_in_init() after every call to SSL_read() or SSL_write() and see if the return value changes from true to false. I don't like that option either because it feels like a hack. Also, I guess it only works with SSL_read(). SSL_write() might send data before I've got a chance to check if the subjectAltName matches with what I expect. 3. Use SSL_set_verify() and provide a callback function. This sounds promising but the callback function gets called for every certificate in the chain. How can I find out whether the certificate in question is the peer's cert and not some intermediate cert? Thanks and regards Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
set_verify_depth w/o effect in 1.0.0-beta2
I'm experimenting with 1.0.0-beta2 and it appears to me that SSL_CTX_set_verify_depth has no effect. This function is supposed to set the maximum depth of the certificate chain that's sent by the peer. It appears to work with 0.9.8g though. I tried to do some debugging and found out that there's an inheritance mechanism in place that creates a new X509_STORE every time a certificate needs to be checked. I guess that this inheritance mechanism is somehow broken because it does not inherits the correct depth value to the newly created X509_STORE. A default value of 100 is always used. Also, the -verify parameter of openssl s_client has little effect. But that's a different issue because s_client does not rely on the set_verify_depth mechanism but rather has its own callback function for this kind of validation. Can anybody confirm these observations? -Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: DTLS: incorrect understanding of MTU
I'm wondering if there's also an error in RFC 4347 section 4.1.1: "[...] the maximum application datagram size, which is the PMTU minus the DTLS per-record overhead [...]" Shouldn't it be phrased like this: the maximum application datagram size, which is the PMTU minus the IP per-packet overhead minus the UDP per-datagram overhead minus the DTLS per-record overhead -Daniel Daniel Mentz wrote: I've got the impression that the DTLS part of OpenSSL is based on an incorrect understanding of the term MTU (Maximum Transmission Unit). My understanding is that the MTU refers to the size of the IP packet including the IP header (usually 20 bytes) and the UDP header (usually 8 bytes) in case UDP is used. This means that I can transfer 1472 bytes of payload if the MTU is 1500 bytes. Now, if I start openssl s_server with the following command line ./openssl s_server -dtls1 -no_ecdhe -timeout -cert large.pem -mtu 1400 and monitor packets with wireshark I can see IP packets with a total length of 1428 bytes. From looking at this I infere that OpenSSL interprets the MTU as the maximum payload size of an UDP packet. If I get rid of the -mtu parameter, rely on Path MTU discovery and set the MTU of the outgoing interface to 1400 I don't get any communication going. But I do see an avalanche of "Destination unreachable (Fragmentation needed)" ICMP messages. I guess that this is due to the incorrect understanding of the MTU. OpenSSL appears to try sending larger packets than allowed by the PMTU. Can anyone confirm this problem? Thanks -Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: DTLS: incorrect understanding of MTU
Hi Michael, I'm using Linux for development but the software should also run on FreeBSD. I also did some research on how to get the result of the Path MTU discovery and I also ended up with this unpleasant #define statement. The only place I could find that #define in a header file was linux/in.h But when I include this file a whole lot of other things break. So I ended up with the same hack. To my disappointment I couldn't find a way to figure out the correct PMTU on FreeBSD. The only feedback you get on this platform is the error EMSGSIZE which essentially tells you that your packet was too big. But it does not tell you how big the packet may be. -Daniel Michael Tüxen wrote: Hi Daniel, I looked at the code for path MTU discovery, which is pretty broken. crypto/bio/bss_diagram.c contains #define IP_MTU 14 /* linux is lame */ if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, &sockopt_len)) < 0 || sockopt_val < 0) which is broken if the socket option ID is not correct. On Mac OS X we have #define IP_MULTICAST_VIF14 /* set/get IP mcast virt. iface */ So it might work on Linux, but one should never define the socket option ID... Which OS are you using? I'll talk to Robin, how we can handle that... Best regards Michael __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: DTLS: incorrect understanding of MTU
Hi Michael, thank you for taking care of this. I'm happy to test any patch you provide. I'd suggest a different approach, though. I would stick to the correct definition of MTU. Otherwise people who look at the code in the future might get confused. d1->mtu should contain the real MTU in my opinion. The 20+8 bytes overhead should be subtracted at a different place. I'm not as familiar with the DTLS code as you are so I can't tell where changes have to be made. Also, I would appreciate if there were a function that I can use as an application developer to find out the maximum number of bytes I can pass to SSL_write() without the resulting IP packet exceeding the MTU. I know that I could just take the MTU and subtract the overhead for the IP, UDP and DTLS Record Header but I think that's a violation of the layering principle. I - as an application developer - don't want to be concerned with the DTLS Record Layer. Best regards, Daniel Michael Tüxen wrote: Hi Daniel, yes, you are right. The command line arg is passed to SSL_set_mtu() which just sets d1->mtu. The rest of the code assumes that d1->mtu does only covers the UDP payload. So we need to fix the handling of SSL_CTRL_SET_MTU to reduce the value by 20+8. Regarding path MTU discovery there seems to be a similar problem, since we have case BIO_CTRL_DGRAM_QUERY_MTU: sockopt_len = sizeof(sockopt_val); if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, &sockopt_len)) < 0 || sockopt_val < 0) { ret = 0; } else { data->mtu = sockopt_val; ret = data->mtu; } break; So I guess this also needs a reduction. Robin, can you provide a patch? Daniel, can you test the patch when it is available? The path MTU discovery might be platform specific... Best regards Michael On May 12, 2009, at 8:24 PM, Daniel Mentz wrote: I've got the impression that the DTLS part of OpenSSL is based on an incorrect understanding of the term MTU (Maximum Transmission Unit). My understanding is that the MTU refers to the size of the IP packet including the IP header (usually 20 bytes) and the UDP header (usually 8 bytes) in case UDP is used. This means that I can transfer 1472 bytes of payload if the MTU is 1500 bytes. Now, if I start openssl s_server with the following command line ./openssl s_server -dtls1 -no_ecdhe -timeout -cert large.pem -mtu 1400 and monitor packets with wireshark I can see IP packets with a total length of 1428 bytes. From looking at this I infere that OpenSSL interprets the MTU as the maximum payload size of an UDP packet. If I get rid of the -mtu parameter, rely on Path MTU discovery and set the MTU of the outgoing interface to 1400 I don't get any communication going. But I do see an avalanche of "Destination unreachable (Fragmentation needed)" ICMP messages. I guess that this is due to the incorrect understanding of the MTU. OpenSSL appears to try sending larger packets than allowed by the PMTU. Can anyone confirm this problem? Thanks -Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
DTLS: incorrect understanding of MTU
I've got the impression that the DTLS part of OpenSSL is based on an incorrect understanding of the term MTU (Maximum Transmission Unit). My understanding is that the MTU refers to the size of the IP packet including the IP header (usually 20 bytes) and the UDP header (usually 8 bytes) in case UDP is used. This means that I can transfer 1472 bytes of payload if the MTU is 1500 bytes. Now, if I start openssl s_server with the following command line ./openssl s_server -dtls1 -no_ecdhe -timeout -cert large.pem -mtu 1400 and monitor packets with wireshark I can see IP packets with a total length of 1428 bytes. From looking at this I infere that OpenSSL interprets the MTU as the maximum payload size of an UDP packet. If I get rid of the -mtu parameter, rely on Path MTU discovery and set the MTU of the outgoing interface to 1400 I don't get any communication going. But I do see an avalanche of "Destination unreachable (Fragmentation needed)" ICMP messages. I guess that this is due to the incorrect understanding of the MTU. OpenSSL appears to try sending larger packets than allowed by the PMTU. Can anyone confirm this problem? Thanks -Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
DTLS: "openssl s_client" broken in 1.0.0-beta2 due to lack of ECDHE support
I built a vanilla openssl-1.0.0-beta2 and tried to run ./openssl s_client -dtls1 against ./openssl s_server -dtls1 To my disappointment it did not work properly. The client reported 3084506760:error:14106044:SSL routines:DTLS1_SEND_CLIENT_KEY_EXCHANGE:internal error:d1_clnt.c:976: The output of the server was 3084805768:error:14102410:SSL routines:DTLS1_READ_BYTES:sslv3 alert handshake failure:d1_pkt.c:1043:SSL alert number 40 After hours of debugging I found a work around which is to use ./openssl s_server -dtls1 -no_ecdhe -timeout and ./openssl s_client -dtls1 -timeout It turned out that the DTLS implementation does not support ECDHE although it happily advertises the ECDHE cipher suites in the "Client Hello" message. The long if-else-if-else-if-chain in dtls1_send_client_key_exchange() simply does not account for ECDHE. So I think the corresponding ciphers should not be included in the list of supported ciphers in the first place. My opinion is that s_client and s_server should always work because they are kind of reference applications. There's little to no documentation on how to use DTLS with OpenSSL. Taking this into account a running example is the only basis you can build on if you're trying to use DTLS in your app. I hope that somebody can fix that problem or at least print out a log message saying "No DTLS support for ECDHE" Thanks Daniel Mentz __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Generate certificate for custom dn
comer merryl wrote: Is it possible to create a certificate with a dn, "uid=user3,ou=People,dc=org,dc=com" Did you try the -subj command option of "openssl req"? Try using -subj "/uid=user3/ou=People/dc=org/dc=com" __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: DTLS server implementation experiences and documentation
Wes Hardaker wrote: http://www.net-snmp.org/wiki/index.php/DTLS_Implementation_Notes Hi Wes, I have some comments regarding your wiki article. But first of all thanks for taking the time writing down all this information: I'm trying to implement IPFIX on top of DTLS so I also made some experiences with DTLS and OpenSSL. I do not use a memory BIO for sending data. I create a datagram BIO instead and let OpenSSL write to this datagram BIO directly. When it comes to receiving data from the UDP socket I create a new memory BIO for *each* packet I received via recvfrom() and pass that memory BIO to OpenSSL. Here's some code: len = read(socket,recvbuf,sizeof(recvbuf)); /* Free existing BIO */ /* TODO: Check whether EOF reached. */ BIO_free(ssl->rbio); /* Create new BIO */ ssl->rbio = BIO_new_mem_buf(recvbuf,len); BIO_set_mem_eof_return(ssl->rbio,-1); I've got a question regarding your solution for sending data: How do ensure that the message boundaries are preserved? What you are doing is basically: 1. Call some SSL_* function like SSL_write, SSL_connect or SSL_accept. 2. Perform a BIO_read on the for_writing BIO 3. Use sendto to send data just read in step 2. What happens if the SSL_* function wants to send more than one UDP datagram at once? I *guess* this could happen if someone wants to send a very large certificate (chain). To me it seems like that you're assuming that OpenSSL sends only a single packet during one invocation of SSL_*, aren't you? If OpenSSL happens to send two packets you're going to concatenate the payload and send out one large datagram instead of two smaller ones. As regards DTLS Cookie handling I suggest to ignore the information hiding/data abstraction principle for now and to access OpenSSL's internal variables in order to find out in which state the OpenSSL state machine is right now. I guess that there's some way to find out whether OpenSSL sent out a HelloVerifyRequest or a ServerHello. If it just sent a HelloVerifyRequest we could just destroy the SSL object and wait for the client to send back the Cookie. Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: DTLS server implementation experiences and documentation
Robin Seggelmann wrote: As a workaround you can use connected UDP sockets. Just use accept() and connect() as you would with TCP connections and create new BIO and SSL objects for every connection. I have tested that and it works pretty well so far. Hi Robin, I'm surprised that you can use accept() on UDP sockets. I checked the man pages of a Debian GNU/Linux system. They say that you can use accept() only with connection-based socket types (SOCK_STREAM, SOCK_SEQPACKET). Is this something specific to FreeBSD? Could you please provide me with more information. Maybe you could make your source code available. Thanks Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: How to detect dead peers with DTLS?
Thank you all for your answers. I think I will go for the hack that misuses re-negotiation as a kind of heartbeat, keep alive or echo request. I tried to avoid this hack at first because it is a computational burden. AFAIK re-negotiation means restarting from scratch which means that expensive public key operations have to be performed. @Michael: Using DTLS on top of SCTP is high on my TODO list. I would be glad if you could help me with this. I'll get back to you with more questions regarding this. I've heard that I'll need your patches for OpenSSL and FreeBSD to make it work. Btw, does OpenSSL support renegotiation when using DTLS? It failed when I tried it with s_client and s_server. I learned from some forum that there's a bug regarding an incorrect message sequence number. Robin Seggelmann provided a patch which has not been merged into the upstream version. Is this still the current status? @Ger: I disagree with you on the fact that I'm trying to convert DTLS into TCP. If I understand Nagendra's Paper correctly DTLS strives to be some kind of secure UDP. Quote: DTLS is explicitly designed to be as compatible as possible with existing datagram communication systems,... ... This property allows applications to simply replace each datagram socket with a secure datagram socket managed by DTLS. DTLS semantics should mimic UDP semantics thus allowing DTLS implementations to mimic the UDP API. end quote I do accept the fact that there might be a loss of datagrams. But when I send out a packet I want to be sure that there's at least a chance that it might reach the receiver. If the receiver crashes and comes up again there's no chance that a packet might ever be decrypted due to the lost state (pre-master secret etc.) in the receiver process. Also, IKE (IPSec) is somewhat similar to DTLS in a sense that it is also unreliable and IKE *does* feature Dead Peer Detection. I'm trying to implement IPFIX according to RFC 5101 which makes support of DTLS on top of UDP mandatory for transmitting IPFIX messages. That's why I'm surprised that there's no simple solution to this problem. Thanks Daniel Ger Hobbelt wrote: On Mon, Jan 19, 2009 at 10:47 AM, Daniel Mentz wrote: Please note that I can not solve this problem via the protocol that I use on [...] the fact the he does not send any data because he does not send data anyway (except Handshake messages like ServerHello, ServerKeyExchange, etc.). I guess IPFIX is a one-way protocol. Well, though I agree with David Schwartz, the key operative word in your text here is 'except' (see snippet of your text above). So the server **does** send packets in return. (Gotcha. ;-) ) Given that you have a ServerKeyExchange or some such (I don't have the protocol documents for IPFIX around here so didn't check for the feasibility of what I mention next), but the obvious hack I would come up with in such a scenario would be providing my own kind of 'keep alive'; this time in the form of periodic requesting a new ServerKey. (It would be a bit akin to SSL, where you can force a renegotiation.) The idea here is that every N minutes or so, you 'renegotiate' a keyset. That's the 'heartbeat' as when that renegotiation fails, you'll know one of your nodes went belly up. Okay, so you lost an undeterminable amount of data between previous key reneg and this one, but I'm sure one would be able to handle/hack that as well. ;-) (And when we travel down this road, we arrive at where the TCP guys already are, as you are trying to convert a fire-and-forget protocol into a guaranteed-delivery protocol. And, just in case, when you say you don't have key renegotiation options in the protocol, how do you come by a key set to start with? I call the above a 'hack' because you are basically looking at reimplementing TCP. (Plus IPFIX, but that's just too obvious, right? ;-) ) __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
How to detect dead peers with DTLS?
Hi everybody, how can I detect a dead server with *DTLS*? I'm developing an application (IPFIX exporter and collector) that only *sends* data using DTLS over UDP. Imagine the collector (DTLS server) crashes and comes up again. The exporter (DTLS client) does not notice the fact that the server went down and keeps on sending data using the old pre-master secret. The only thing the server can do is to drop those packets because due to the crash he lost the pre-master secret and also the whole state that constitutes the SSL object. Please note that the underlying protocol which is UDP - as opposed to TCP - does *not* tell me that the peer died. I might get some ICMP port-unreachable messages but I don't want to rely on that. Is there some kind of Dead Peer Detection like in the IPSec/IKE protocol that allows me to verify that my peer is still alive? In case the peer died I would just backup and initiate a new DTLS connection from scratch. Also, this mechanism would be useful to keep NAT mappings alive. Please note that I can not solve this problem via the protocol that I use on top of DTLS - which is IPFIX - because IPFIX - by definition - only *sends* but does not receive data. I.e. I can not infer that the server crashed from the fact the he does not send any data because he does not send data anyway (except Handshake messages like ServerHello, ServerKeyExchange, etc.). I guess IPFIX is a one-way protocol. Thanks Daniel __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org