Re: Use TLS over UDP connection
On Sun, 2013-02-24 at 22:26 -0500, Dave Thompson wrote: TLS depends on TCP's reliable in-order transport. DTLS basically re-implements enough of TCP to make TLS functionality work. That isn't entirely true. Or at least it's misleadingly phrased. DTLS copes with packet loss and packet re-ordering. If your data are transported over DTLS you'd best make sure your application is expecting to cope with packet loss and re-ordering too. DTLS does its own retries of the handshake messages, and I suppose strictly speaking that *is* enough of TCP to make DTLS functionality work. But you should be careful not to give the impression that DTLS will magically give you an in-order, guaranteed-delivery data stream. It won't; it's still a datagram protocol at heart. -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation smime.p7s Description: S/MIME cryptographic signature
How to check client certificate for expiration
In my VPN client I'd like to warn the user when their certificate is almost out of date. Is there a way to get the client certificate from the SSL_CTX after the client cert has been loaded? As discussed elsewhere, it's quite painful for an application simply to undertake the task of load a client certificate provided by the user. If I want to check the notAfter date of the certificate, however, it seems to get even more painful. I can't find a way to get the certificate back from the CTX, so... ... for PKCS#12 certs, we keep a pointer to the X509 structure we add as we parse it. ... for PEM certs and TPM 'blobs' we actually have to re-parse the file because SSL_CTX_use_certificate_chain_file() doesn't let us see the X509 (and the alternative is open-coding a reimplementation of that function). On the whole, it just makes the whole thing even more horrid. And I was quite pissed off with it already. Am I missing something? http://git.infradead.org/users/dwmw2/openconnect.git/commitdiff/1b9a2db4 -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: FUNCTION FOR LOADING THE CERTIFICATE
On Thu, 2010-08-26 at 14:41 +0530, Raj wrote: Can anybody tell me the function for loading a certificate file (from my local hdd) to X509 object http://www.advogato.org/person/dwmw2/diary/205.html -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: NameConstraints are not being applied (or I don't know how to enforce them?)
On Thu, 2010-06-03 at 21:35 -0400, Victor Duchovni wrote: The problem is that only the application knows which names are those of the peer it tried to reach. True, but the app could easily provide that information to a library function. If you look at the 250 lines of code I referenced, almost none of that is actually app-specific. My code could be abstracted to take the app-specific information as arguments without too much pain. -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: NameConstraints are not being applied (or I don't know how to enforce them?)
On Thu, 2010-06-03 at 13:47 -0400, Victor Duchovni wrote: Generally, OpenSSL does not verify peer names, only the certificate trust chain, and peername checks are left up to applications. Which is a shame... I'm far too stupid to be writing code like http://git.infradead.org/users/dwmw2/openconnect.git?a=blob;f=ssl.c;hp=v2.25#l436 for myself, and I would much rather have used a library function ;) -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: X509 Verify callback
On Mon, 2010-05-10 at 14:43 -0400, Chris Bare wrote: Is there a way get have X509_verify_cert retry it's path building after it gets an X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT? My idea is to implement a verify callback that uses the AIA information to download the issuer cert and add it to the stack of untrusted certs. Is this possible, or would I have to let X509_verify_cert error out and call it again? How about... int my_get_issuer_func(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { int ret = X509_STORE_CTX_get1_issuer(issuer, ctx, x); if (ret 0) return ret; /* Do whatever you need to look up the issuer... */ } ... and somewhere else in your SSL_CTX setup: X509_STORE *store = SSL_CTX_get_cert_store(vpninfo-https_ctx); store-get_issuer = my_get_issuer_func; -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: X509 Verify callback
On Tue, 2010-05-11 at 09:58 -0400, Chris Bare wrote: That's almost perfect, but doesn't putting it inside the X509_STORE like this tell the rest of the code it's trusted? If I'm downloading it using AIA I can't trust it and still need to chain up to a trusted root. Hm, true. But surely there's something else (ctx-verify_cb or ctx-verify?) that lets you fix that up too? -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: PKCS12_parse() SEGV.
On Sun, 2010-05-09 at 12:12 +0100, David Woodhouse wrote: Although that's OK for my purposes, I think it's actually a bug. The man page for PKCS12_parse() says that *ca can be a valid stack, in which case additional certificates are appended to *ca. It _doesn't_ say oh, but if parsing fails because the user fat-fingered the passphrase, we'll completely free your carefully pre-generated stack in *ca and set *ca to NULL Surely it shouldn't be freeing the _original_ contents of the stack which was passed in *ca? Those should be preserved. My test was against 1.0.0-beta4, from Fedora 12. It looks like this has since been fixed. In older versions of OpenSSL (1.0.0-beta2), the failure mode is actually ... we'll free your carefully pre-generated stack in *ca but for extra fun, we leave *ca pointing to the now-freed memory. Which is the bug that I tripped over. We should either backport the whole fix to the 0.9.8 branch, or at the very least do this: --- crypto/pkcs12/p12_kiss.c5 Nov 2008 18:36:46 - 1.20.2.1 +++ crypto/pkcs12/p12_kiss.c9 May 2010 12:27:42 - @@ -134,7 +134,10 @@ int PKCS12_parse(PKCS12 *p12, const char if (pkey *pkey) EVP_PKEY_free(*pkey); if (cert *cert) X509_free(*cert); - if (ca) sk_X509_pop_free(*ca, X509_free); + if (ca) { + sk_X509_pop_free(*ca, X509_free); + *ca = NULL; + } return 0; } -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
PKCS12_parse() SEGV.
With OpenSSL 0.9.8n this test program segfaults the second time it tries to parse the PKCS#12 file. It was fixed for OpenSSL 1.0.0 by this commit: http://cvs.openssl.org/chngview?cn=17957 Starting program: /home/dwmw2/p12test .cert/certificate.p12 Enter PKCS#12 passphrase: 140737353934504:error:23076071:PKCS12 routines:PKCS12_parse:mac verify failure:p12_kiss.c:121: Parse PKCS#12 failed (wrong passphrase?) Enter PKCS#12 passphrase: Program received signal SIGSEGV, Segmentation fault. __libc_free (mem=0x31) at malloc.c:3709 3709 if (chunk_is_mmapped(p)) /* release mmapped memory. */ (gdb) bt #0 __libc_free (mem=0x31) at malloc.c:3709 #1 0x00417d5d in CRYPTO_free () #2 0x0044396d in ASN1_STRING_free () #3 0x0043f2cd in ASN1_primitive_free () #4 0x0043f69f in ASN1_template_free () #5 0x0043f586 in asn1_item_combine_free () #6 0x0043f6d5 in ASN1_item_free () #7 0x0042e2b4 in sk_pop_free () #8 0x0045d643 in PKCS12_parse () #9 0x00401c69 in main () My dirty workaround for now is just to add a deliberate memory leak in my application just before the 'goto retry': #if OPENSSL_VERSION_NUMBER 0x1002 ca = sk_X509_new_null(); #endif Any better suggestions? I still stand by everything I said in http://www.advogato.org/person/dwmw2/diary/205.html about loading certificates, FWIW. -- dwmw2 #include stdio.h #include openssl/ssl.h #include openssl/err.h #include openssl/engine.h #include openssl/evp.h #include openssl/pkcs12.h #include openssl/x509v3.h int main(int argc, char **argv) { FILE *f; EVP_PKEY *pkey = NULL; char pass[PEM_BUFSIZE]; X509 *cert = NULL; PKCS12 *p12; STACK_OF(X509) *ca; SSL_library_init(); ERR_clear_error(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); if (argc != 2) { fprintf(stderr, Need PKCS#12 filename\n); exit(1); }; f = fopen(argv[1], r); if (!f) { perror(fopen); exit(1); } p12 = d2i_PKCS12_fp(f, NULL); if (!p12) { fprintf(stderr, d2i_PKCS12_fp failed\n); exit(1); } ca = sk_X509_new_null(); retry: if (EVP_read_pw_string(pass, PEM_BUFSIZE, Enter PKCS#12 passphrase:, 0)) { fprintf(stderr, Failed to obtain passphrase\n); exit(1); } if (!PKCS12_parse(p12, pass, pkey, cert, ca)) { unsigned long err = ERR_peek_error(); ERR_print_errors_fp(stderr); if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 ERR_GET_FUNC(err) == PKCS12_F_PKCS12_PARSE ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) { fprintf(stderr, Parse PKCS#12 failed (wrong passphrase?)\n); goto retry; } fprintf(stderr, Failed\n); exit(1); } printf(Succeeded\n); return 0; }
Re: PKCS12_parse() SEGV.
On Fri, 2010-05-07 at 19:24 +0200, Dr. Stephen Henson wrote: Setting ca to NULL if it fails should work. That should be done in PKCS12_parse() on error. AIUI I don't want it to be NULL; I need it to be an empty stack. I need the returned 'extra' certs so that I can work around RT#1942 on the server. -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: locate key for p12 certificate
On Thu, 2010-04-08 at 08:10 -0400, Patrick Patterson wrote: So, the short answer is - until you can convince the administrators of the server that you are proxying for to hand over their private keys, what you want to do is not possible. Well, what he wants to do is just see the traffic in the HTTP session -- he seemed to suggest that he only needs to see the POST string. Since the client is running on one of his own machines, that really shouldn't be hard to achieve. On Thu, 2010-04-08 at 00:45 -0700, peter23452345 wrote: (php curl doesnt provide visibility into the http post string and i need to see this) Fix this, and your problem is solved. -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: AES speed?
On Fri, 2010-04-02 at 15:57 -0400, Victor Duchovni wrote: The performance of the 1.0.0 AES algorithm as reported by openssl speed, appears to be much lower with block sizes of 16, 64 and 256 bytes than with previous releases. Larger block sizes of 1024 and 8192 bytes show good performance. Is this to be expected? Tests were run on a RedHat Linux system with an Intel X86-64 CPU for both the 32-bit and 64-bit builds of the code. Should lower AES performance for small buffer sizes be expected with 1.0.0, or is speed aes reporting inaccurate data? I investigated this a little. You compared various 0.9.x revisions with 1.0.0, but there's a _big_ jump between those branches, and I wanted to look at the history of the branch which became 1.0.0 (or current HEAD, which is close enough). Obviously the first thing to do was to import the code into a modern version control system so that I could actually do useful things with it. I used Keith Packard's parsecvs to create a git repository, which I've put at http://git.infradead.org/users/dwmw2/openssl-parsecvs.git My testing was done on an 8-way Tylersburg-HEDT system, with cpu speed pinned at 3GHz to avoid complications from power saving. It runs Fedora 11, with GCC 4.4.1. I tested only 64-bit. I started with current HEAD, then stepped back by 100 commits at a time, rebuilding with default options from ./config then running 'openssl speed aes' and charting the results -- which are at http://david.woodhou.se/aesspeed.png (and .dat and .gnuplot). As you can see, the results all got much faster once I got back in time to about mid-2007. Using 'git-bisect' I was able to find the offending commit which had caused the performance degradation: http://git.infradead.org/users/dwmw2/openssl-parsecvs.git/commitdiff/25e9f96b Another interesting thing that you can't quite make out on the graph is that there was a significant _improvement_ in aes128-cbc and aes192-cbc performance on smaller sizes immediately before it got worse. See the data for commit id 1a1c46a9f4df4fa3fcfa5343cdd7136e164bae27 in the raw results. Note that I didn't bisect this change so it's almost certainly not precisely that commit which caused it. And that aes256-cbc performance got worse while aes128-cbc and aes192-cbc got better. I resisted the temptation to include AESNI scores on the graph; they'd have screwed up the scale :) -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: AES speed?
On Wed, 2010-04-07 at 16:00 -0400, Victor Duchovni wrote: Can someone confirm that what we are seeing is a work-around for DJB's cache timing attack on AES? If so, I would guess that the timing attack is believed to be impractical for large blocks, so the fast path is used only for sufficiently large inputs... You seem to be right. The 32-bit version is better documented... http://git.infradead.org/users/dwmw2/openssl-parsecvs.git/commitdiff/89be25a2 ...The current size limit of +# 512 bytes is chosen to provide same [diminishigly low] probability +# for cache-line to remain untouched in large chunk operation with +# large S-box as for single block operation with compact S-box and +# surely needs more careful consideration... -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: associating a cert with a private key
On Sat, 2010-03-27 at 22:41 -0700, sd dd wrote: haven't had any luck with this alias so far, thought I've try it one more time :) here is my understanding of a cert signing request, client create a key pair, send the public key to server for signing server send back the signed cert, now, my question is, from the server response I am able to get a public key, then how do i associate the private key with this public key? any code example to do this? I'm not entirely sure what you're trying to do. Are you suggesting that you'll have submitted more than one signing request at a time, so you'll have _many_ private keys lying around and you don't know which one is associated with which response from the server? If so, perhaps the X509_check_private_key() function in crypto/x509/x509_cmp.c may be relevant to you? You could iterate over the available private keys, looking for one which matches the public key in the certificate you get back from the server. Or you could just keep better track of your outstanding requests? :) -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
X509_PURPOSE_ANY with ssl client and OpenSSL 0.9.8k
We've seen a number of Cisco AnyConnect VPN servers which don't have the SSL server purpose bit set in their certificate. We have a workaround¹ but I've just received a complaint that this workaround doesn't work correctly with older (0.9.8k) versions of OpenSSL. Does the patch below make sense? It seems to work... --- openconnect-2.22/ssl.c +++ openconnect-2.22/ssl.c @@ -474,6 +474,14 @@ void workaround_openssl_certchain_bug(struct openconnect_info *vpninfo, X509_STORE_CTX_cleanup(ctx); } +static int ssl_app_verify_callback(X509_STORE_CTX *ctx, void *arg) +{ + /* We've seen certificates in the wild which don't have the + purpose fields filled in correctly */ + X509_VERIFY_PARAM_set_purpose(ctx-param, X509_PURPOSE_ANY); + return X509_verify_cert(ctx); +} + int openconnect_open_https(struct openconnect_info *vpninfo) { method_const SSL_METHOD *ssl3_method; @@ -649,9 +657,13 @@ int openconnect_open_https(struct openconnect_info *vpninfo) } } - /* We've seen certificates in the wild which don't have the - purpose fields filled in correctly */ - SSL_CTX_set_purpose(vpninfo-https_ctx, X509_PURPOSE_ANY); + /* We just want to do: + SSL_CTX_set_purpose(vpninfo-https_ctx, X509_PURPOSE_ANY); + ... but it doesn't work with OpenSSL 0.9.8k because of + problems with inheritance (fixed in v1.1.4.6 of + crypto/ssl/x509_vpm.c) so we have to play silly buggers + instead. */ + SSL_CTX_set_cert_verify_callback(vpninfo-https_ctx, ssl_app_verify_callback, NULL); SSL_CTX_set_default_verify_paths(vpninfo-https_ctx); if (vpninfo-cafile) -- dwmw2 ¹ http://git.infradead.org/users/dwmw2/openconnect.git/blob/b98c7e15:/ssl.c#l652 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: TLS compatibility problem -- can connect to server with NSS but not OpenSSL.
On Wed, 2009-06-03 at 17:59 -0400, Victor Duchovni wrote: The SSL_CTX_use_certificate_chain_file() API is a very admin friendly way to support installation of cert + chain and even key + cert + chain, as the key can also be stored in the same file (ideally mode 0600 or passphrase-protected). Much like a PKCS#12 file, in fact. I'll make my VPN client use SSL_CTX_use_certificate_chain_file(), and I'll also look at making our cert-fetching scripts generate an appropriate file. Thanks. In the meantime the bug seems to have been fixed on the server so it doesn't _need_ me to submit a full certificate chain any more. Either they've deployed a fix for RT#1942, or the admins have just removed the old, conflicting CA certs from the CA bundle. -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: TLS compatibility problem -- can connect to server with NSS but not OpenSSL.
On Tue, 2009-06-02 at 21:39 -0400, Victor Duchovni wrote: The CAfile is for verification, not for sending alon the trust chain of a given certificate. OpenSSL currently _does_ use the CAfile for sending along the trust chain of its client certificate. It's buggy, but it tries :) DO NOT append your CAfile to your certificate, instead include just the leaf cert, then the issuing CAs bottom-up in the right order. AFAICT that doesn't make any difference -- OpenSSL doesn't use them from there anyway (unless it's a PKCS#12 file, but the client application has to handle all that manually anyway). -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: TLS compatibility problem -- can connect to server with NSS but not OpenSSL.
On Wed, 2009-06-03 at 15:02 -0400, Victor Duchovni wrote: with SSL_CTX_use_certificate_chain_file() the entire trust chain is loaded from the provided file bottom-up order. The first certificate is the leaf and must match the private key provided. Ah, right. Most files I've encountered have had only the _one_ certificate. The code path you describe seems to be labelled with /* A Thawte special :-) */ throughout the addition and usage of those extra certs -- is that really the way it's _supposed_ to be done? -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: TLS compatibility problem -- can connect to server with NSS but not OpenSSL.
On Mon, 2009-06-01 at 17:15 -0400, Victor Duchovni wrote: I found another strange behaviour that I didn't expect -- the _order_ of the certificates in the cafile seems to be important. Yes, the TLS protocol requires the trust chain to be delivered bottom-up. That makes sense, but we're talking about the order of the certificates in the cafile, not on the wire. OpenSSL really ought to get that right. The problem turned out to be that OpenSSL was picking the _wrong_ certificates. http://rt.openssl.org/Ticket/Display.html?id=1942user=guestpass=guest -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
[RANT] Loading a client certificate makes my head hurt.
Q: My application takes a filename for a client certificate on the command line. What is the OpenSSL function to load and use it? A: Well, we make this lots of fun for you -- it would be boring if there was just one function which you could pass the filename to. You have to write 230 lines of code instead First you have to check for yourself what type of file it is -- is it a PKCS#12 file, is it a PEM file with a key in it, or is it a TPM key 'blob'? No, there's no function which determines that for you -- you have to do it yourself. And depending on the answer, you have to do three entirely different things to load the key. To make things even more fun, those three file types have _wildly_ different ways to handle their passphrase/PIN: For a PEM file, you can't tell OpenSSL the passphrase in advance -- if the user gave it on the command line, you have to manually override the user interface function that OpenSSL will call, and make your replacement function return the pre-set passphrase. Or if you _do_ ask the user, you've got no way to easily tell whether the user got the passphrase wrong; if they get it wrong (and type 4 or more characters) then the 'load key' function will fail and you have to compare against a special error code, which may differ from version to version of OpenSSL because it has internal function names. Just for variety, if the user enters a wrong passphrase with _fewer_ than 4 characters, they'll get _no_ feedback and will just be asked again. For a PKCS#12 file, it's the other way round -- you _have_ to give the passphrase in advance, so you have to ask the user for it yourself. Even if the file isn't actually encrypted -- because you don't know that yet. For a TPM file it's saner -- you can _either_ set the PIN in advance or otherwise OpenSSL will ask the user for it _if_ necessary. But you do have to jump through various other hoops to use the TPM 'engine', instead of just pointing OpenSSL at the file and having everything handled for you. Have I got any parts of the above answer wrong? Is there anyone out there who thinks that this is a _sensible_ state of affairs? This is my load_certificate() function -- could it be simpler? Surely OpenSSL ought to provide a function with basically equivalent functionality, rather than leaving it to the client application? Am I missing something? (Unless specified on the command line, vpninfo-cert_type will be CERT_TYPE_UNKNOWN. When the autodetection is _working_ there's no real need to specify it on the command line, of course.) static int pem_pw_cb(char *buf, int len, int w, void *v); static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12); static int load_tpm_certificate(struct openconnect_info *vpninfo); static int load_certificate(struct openconnect_info *vpninfo) { vpninfo-progress(vpninfo, PRG_TRACE, Using certificate file %s\n, vpninfo-cert); if (vpninfo-cert_type == CERT_TYPE_PKCS12 || vpninfo-cert_type == CERT_TYPE_UNKNOWN) { FILE *f; PKCS12 *p12; f = fopen(vpninfo-cert, r); if (!f) { vpninfo-progress(vpninfo, PRG_ERR, Failed to open certificate file %s\n, vpninfo-cert); return -ENOENT; } p12 = d2i_PKCS12_fp(f, NULL); fclose(f); if (p12) return load_pkcs12_certificate(vpninfo, p12); /* Not PKCS#12 */ if (vpninfo-cert_type == CERT_TYPE_PKCS12) { vpninfo-progress(vpninfo, PRG_ERR, Read PKCS#12 failed\n); report_ssl_errors(vpninfo); return -EINVAL; } /* Clear error and fall through to see if it's a PEM file... */ ERR_clear_error(); } /* It's PEM or TPM now, and either way we need to load the plain cert: */ if (!SSL_CTX_use_certificate_file(vpninfo-https_ctx, vpninfo-cert, SSL_FILETYPE_PEM)) { vpninfo-progress(vpninfo, PRG_ERR, Load certificate failed\n); report_ssl_errors(vpninfo); return -EINVAL; } if (vpninfo-cert_type == CERT_TYPE_UNKNOWN) { FILE *f = fopen(vpninfo-sslkey, r); char buf[256]; if (!f) { vpninfo-progress(vpninfo, PRG_ERR, Failed to open certificate file %s\n, vpninfo-cert); return -ENOENT; } buf[255] = 0; while
Re: TLS compatibility problem -- can connect to server with NSS but not OpenSSL.
On Tue, 2009-05-26 at 11:21 -0400, Victor Duchovni wrote: The server is unhappy with the client certificate chain, and drops the connection if the client certificate trust chain does not verify. The same server is willing to accept clients with no certificates at all. The server is lame. Don't use it with client certificates that don't have a complete trust chain. That makes a certain amount of sense; thanks. Forgive my ignorance -- is there a way to ensure that the full trust chain is included in the certificate itself, rather than having to provide the -CAfile option to openssl(1) separately? I naïvely tried just appending the contents of a working cafile to the certificate.pem file but that's not sufficient. I found another strange behaviour that I didn't expect -- the _order_ of the certificates in the cafile seems to be important. My original scripts which interact with the company's internal PKI infrastructure would download a bunch of certificates separately and I would shove them all in a single file with a command line like: for a in *.crt ; do cat $a ; echo company-certchain.crt The resulting file would work, and allow me to connect to the server. So I modified the scripts to create one big file just the same... except that they'd be stored in the order that they were downloaded, instead of alphabetical order by filename as the above shell command gave me. And _that_ cafile doesn't work; I still get summarily disconnected. Does ordering in trustchain files matter? If so, how do I ensure I get the right order? -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: TLS compatibility problem -- can connect to server with NSS but not OpenSSL.
On Sun, 2009-05-31 at 10:13 +0100, David Woodhouse wrote: On Tue, 2009-05-26 at 11:21 -0400, Victor Duchovni wrote: The server is unhappy with the client certificate chain, and drops the connection if the client certificate trust chain does not verify. The same server is willing to accept clients with no certificates at all. The server is lame. Don't use it with client certificates that don't have a complete trust chain. That makes a certain amount of sense; thanks. Forgive my ignorance -- is there a way to ensure that the full trust chain is included in the certificate itself, rather than having to provide the -CAfile option to openssl(1) separately? I naïvely tried just appending the contents of a working cafile to the certificate.pem file but that's not sufficient. I found another strange behaviour that I didn't expect -- the _order_ of the certificates in the cafile seems to be important. My original scripts which interact with the company's internal PKI infrastructure would download a bunch of certificates separately and I would shove them all in a single file with a command line like: for a in *.crt ; do cat $a ; echo company-certchain.crt The resulting file would work, and allow me to connect to the server. So I modified the scripts to create one big file just the same... except that they'd be stored in the order that they were downloaded, instead of alphabetical order by filename as the above shell command gave me. And _that_ cafile doesn't work; I still get summarily disconnected. Does ordering in trustchain files matter? If so, how do I ensure I get the right order? I implemented PKCS#12 support in the OpenConnect VPN client¹, and created a PKCS#12 version of my certificate including the required trust chain -- by appending the full trust chain file to my certificate.pem file and then running: openssl pkcs12 -export -out cert.p12 -in cert.pem -inkey priv-key.pem It only works if I reverse the order of the certificates it contains, with a patch like the following: diff --git a/ssl.c b/ssl.c index 6f47568..3a8170c 100644 --- a/ssl.c +++ b/ssl.c @@ -163,7 +163,12 @@ static int load_pkcs12_certificate(struct openconnect_info } if (ca) { + STACK_OF(X509) *ca2 = sk_X509_new_null(); + while ((cert = sk_X509_pop(ca))) { + sk_X509_push(ca2, cert); + } + while ((cert = sk_X509_pop(ca2))) { char buf[200]; X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); I tried sk_X509_sort(ca) but that just segfaults... -- dwmw2 ¹ http://git.infradead.org/users/dwmw2/openconnect.git __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: TLS compatibility problem -- can connect to server with NSS but not OpenSSL.
On Thu, 2009-05-21 at 22:44 +0100, David Woodhouse wrote: I'm trying to connect to an HTTPS server, and my connection is being rejected when I use a client certificate: [dw...@macbook ~]$ openssl s_client -cert $CERT -connect $SERVER:443 -crlf -tls1 CONNECTED(0003) depth=1 /C=US/O=Foo Corporation/CN=Foo Intranet Basic Issuing CA 2A verify error:num=20:unable to get local issuer certificate verify return:0 24620:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:530: I've discovered that it works if I also use the '-CAfile' option and give it the appropriate certificate chain. If I use an empty CAfile or one with the wrong certificates in it, the server still hates me. But NSS can connect without having to have the certificate chain in place locally. Is there a way to make OpenSSL behave similarly, so that it doesn't upset the server? -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
TLS compatibility problem -- can connect to server with NSS but not OpenSSL.
I'm trying to connect to an HTTPS server, and my connection is being rejected when I use a client certificate: [dw...@macbook ~]$ openssl s_client -cert $CERT -connect $SERVER:443 -crlf -tls1 CONNECTED(0003) depth=1 /C=US/O=Foo Corporation/CN=Foo Intranet Basic Issuing CA 2A verify error:num=20:unable to get local issuer certificate verify return:0 24620:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:530: Making the _same_ connection with curl (built to use NSS) is working. Looking at a packet capture, the only obvious difference I see is in the structure of the packet which we send with our client certificate. Looking at the OpenSSL traffic in wireshark, it looks like this: - Secure Socket Layer - TLSv1 Record Layer: Handshake Protocol: Certificate - Secure Socket Layer - TLSv1 Record Layer: Handshake Protocol: Client Key Exchange - TLSv1 Record Layer: Handshake Protocol: Certificate Verify - TLSv1 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec - TLSv1 Record Layer: Handshake Protocol: Encrypted Handshake Message The one from NSS that _works_ looks like this: - Secure Socket Layer - TLSv1 Record Layer: Handshake Protocol: Multiple Handshake Messages - Handshake Protocol: Certificate - Handshake Protocol: Client Key Exchange - Handshake Protocol: Certificate Verify - Secure Socket Layer - TLSv1 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec - TLSv1 Record Layer: Handshake Protocol: Encrypted Handshake Message Is it possible that the server would be objecting to the fact that the Certificate/Client Key Exchange/Certificate Verify messages from OpenSSL aren't all in the same TLSv1 record? There's another distinction which I don't understand -- why is wireshark grouping TLSv1 records under 'Secure Socket Layer' heading, and how does it decide where one 'Secure Socket Layer' object ends and the next one starts? I've given a screenshot of wireshark's display at http://david.woodhou.se/handshake.png in case the above description doesn't do it justice. The working connection with NSS is on the right; the failing connection with OpenSSL is on the left. This happens for me with 0.9.8f, 0.9.8k and 1.0.0-beta2 at least; I didn't try any more versions. The server is some Cisco VPN box, but for the purpose of this discussion it's just an HTTPS server (and firefox works with it too). When I _don't_ use a client certificate, I can connect fine -- of course I can't authenticate, but at least the HTTP exchange works well enough to tell me to sod off. It's only when I use a certificate that it will reject my connection completely. I get an ACK to my packet described above, then a FIN. That's it. The certificate in both cases is the same. -- dwmw2 __ 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
On Sat, 2009-01-24 at 00:13 +0100, Georges Le grand wrote: I wonder if you could give out a reference on how to establish a VPN using DTLS or to tell how to do so. We are just using Cisco's AnyConnect VPN, which runs over an HTTPS 'CONNECT' and will use DTLS for subsequent data transfer if it can. The client code is at git://git.infradead.org/users/dwmw2/openconnect.git (viewable in gitweb by changing git:// to http:// in that URL). That code works on Linux and MacOS, and if anyone wants to provide a patch to make it work on other BSD systems that would be much appreciated. Since Cisco use an old version of OpenSSL on the server side, you'll need to patch OpenSSL to make it compatible with its own pre-RFC version of DTLS -- see http://rt.openssl.org/Ticket/Display.html?id=1751 for the patch. The VPN will work over HTTPS if you don't patch OpenSSL, but VPN over TCP is a very suboptimal solution. I haven't done server-side code yet; the point of this was to interoperate with the existing servers, and I have no immediate need to _replace_ them. It really wouldn't be hard though -- it's all fairly trivial stuff. You might also be interested in http://campagnol.sourceforge.net/ -- dwmw2 __ 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
On Sat, 2009-01-24 at 23:03 +0100, Georges Le grand wrote: So it is alike SSL VPN with data encapsulated into HTTP Packets, but I don't get how does HTTP run over UDP. Probably best explained by the code... it just uses HTTP for the initial setup -- a CONNECT request with an HTTP cookie for authentication, and you get IP address etc. in the headers of the response. Then you're connected with an SSL connection, you can forget HTTP, and run IP packets over that connection. In the headers of the initial exchange you _also_ set up parameters for a DTLS connection, over which you can pass packets. -- dwmw2 __ 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
On Thu, 2009-01-22 at 06:10 +0100, Robin Seggelmann wrote: To avoid getting into trouble with already fixed bugs you should apply the patches I sent to the dev list. I'll set up a website with a patch collection and some instructions soon. Is there anyone who actually cares about DTLS and getting patches applied? I've had patches to make OpenSSL capable of talking to production servers out there in the wild, which use the OpenSSL-specific pre-RFC version of DTLS and I've been able to write a complete VPN client along with NetworkManager support, and get it into Linux distributions, in the time it's taken to get the patch into OpenSSL... and I'm still waiting... It's getting to the point where I wonder if it would be quicker and easier just to reimplement DTLS in GNUTLS and use that. -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: DTLS clue requested: epoch numbers
On Fri, 2008-09-26 at 13:46 -0700, David Woodhouse wrote: At the worst, I should be able to reverse-engineer the library I have. The first failure seems to have been a discrepancy in epoch numbers. Comparing behaviour of their library and 0.9.8e, I find that theirs is adding '00 01 00 00 00 00 00 00' to a digest at some point, while 0.9.8e adds '00 00 00 00 00 00 00 00'. This is called from tls1_mac(), when it's adding the 8 bytes of ssl-s3-read_sequence to the MAC. The 0.9.8e library then rejects the Server Hello because of the MAC failure, which was the original failure mode I was observing. If I hack EVP_DigestUpdate() to fix that single byte for that one call, then the MAC check in dtls1_process_record() succeeds, although fairly unsurprisingly I get a later failure -- in ssl3_get_finished() when s-s3-tmp.peer_finish_md doesn't contain what it should: 12778:error:1408C095:SSL routines:SSL3_GET_FINISHED:digest check failed:s3_both.c:235: I'm still entirely clueless about the protocol, but it seems the top 16 bits of ssl-s3-read_sequence are supposed to be an epoch number. But it's getting set to all zeroes in dtls1_reset_seq_numbers() even when the epoch is non-zero. Having narrowed it down that far, does anyone remember a change which might have caused this? I tried removing my hack from EVP_DigestUpdate and instead hacking dtls1_reset_seq_numbers() to call s2n(epoch, seq) to put the epoch in place after the memset. That makes no difference -- I still get the same later failure. Which I'll now investigate, but it's probably going to turn out to be due to the wrongness of my 'fix' for the epoch thing. As I said, I'm fairly clueless. I've converted the OpenSSL CVS history into git so that I can try to look through it, but I don't see anything which jumps out as being relevant. There's a commit entitled 'Liberate dtls from BN dependency. Fix bug in replay/update.' which helpfully hides an unspecified bug fix in amongst 300-odd lines of more cosmetic changes in one commit, but that doesn't seem to be it. As before, my test case is http://david.woodhou.se/dtls-test.c -- and needs to be run against a version of OpenSSL which still uses 0x100 for DTLS1_VERSION. -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: DTLS clue requested: epoch numbers
On Sun, 2008-09-28 at 18:56 +0100, David Woodhouse wrote: On Fri, 2008-09-26 at 13:46 -0700, David Woodhouse wrote: At the worst, I should be able to reverse-engineer the library I have. The first failure seems to have been a discrepancy in epoch numbers. And the others are due to patches which were committed to OpenSSL later -- in particular, 'RFC4347 says HelloVerifyRequest resets Finished MAC', which moves a call to ssl3_init_finished_mac(), and Make DTLS1 record layer MAC calculation RFC compliant, which sets the appropriate version numbers in the packet in tls1_mac(). The full patch against 0.9.8e which makes this work (or at least successfully negotiate and pass _some_ traffic -- I don't vouch for later epoch changes) is below. Next step would be to make it work in something newer. And preferably with the RFC-defined version of the protocol instead of the old one. Their client does seem to respond with the 'real' DTLS1 version if we try that instead of using DTLS1_BAD_VER. And it has a CCS header length of only 1 byte its responses, so it really is doing something different and not just parrotting the version number. But just taking 0.9.8f and setting the epoch in dtls1_reset_seq_numbers() as in the patch below isn't sufficient -- I get the same record mac failure that I started with. This time it's going to be a little harder to guess what variant of the new protocol they're using, because I don't have any implementation of that -- and I'm not even sure it's _working_ on the server side. So I suspect my best course of action now would be to somehow make it possible to use the older version of DTLS in a current OpenSSL, for compatibility? It's likely to be the only thing that's _tested_ against Cisco servers anyway. Index: ssl/d1_clnt.c === RCS file: /home/dwmw2/openssl-cvs/openssl/ssl/d1_clnt.c,v retrieving revision 1.3.2.6 diff -u -p -r1.3.2.6 d1_clnt.c --- ssl/d1_clnt.c 5 Dec 2005 17:32:19 - 1.3.2.6 +++ ssl/d1_clnt.c 28 Sep 2008 23:49:54 - @@ -214,8 +214,6 @@ int dtls1_connect(SSL *s) /* don't push the buffering BIO quite yet */ - ssl3_init_finished_mac(s); - s-state=SSL3_ST_CW_CLNT_HELLO_A; s-ctx-stats.sess_connect++; s-init_num=0; @@ -225,6 +223,10 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_CLNT_HELLO_B: s-shutdown=0; + + /* HelloVerifyRequest resets Finished MAC */ + ssl3_init_finished_mac(s); + ret=dtls1_client_hello(s); if (ret = 0) goto end; Index: ssl/d1_pkt.c === RCS file: /home/dwmw2/openssl-cvs/openssl/ssl/d1_pkt.c,v retrieving revision 1.4.2.5 diff -u -p -r1.4.2.5 d1_pkt.c --- ssl/d1_pkt.c29 Nov 2006 14:45:13 - 1.4.2.5 +++ ssl/d1_pkt.c28 Sep 2008 23:53:18 - @@ -1718,12 +1718,12 @@ dtls1_reset_seq_numbers(SSL *s, int rw) { unsigned char *seq; unsigned int seq_bytes = sizeof(s-s3-read_sequence); + int epoch; if ( rw SSL3_CC_READ) { seq = s-s3-read_sequence; - s-d1-r_epoch++; - + epoch = ++s-d1-r_epoch; pq_64bit_assign((s-d1-bitmap.map), (s-d1-next_bitmap.map)); s-d1-bitmap.length = s-d1-next_bitmap.length; pq_64bit_assign((s-d1-bitmap.max_seq_num), @@ -1738,10 +1738,11 @@ dtls1_reset_seq_numbers(SSL *s, int rw) else { seq = s-s3-write_sequence; - s-d1-w_epoch++; + epoch = ++s-d1-w_epoch; } memset(seq, 0x00, seq_bytes); + s2n(epoch,seq); } #if PQ_64BIT_IS_INTEGER Index: ssl/t1_enc.c === RCS file: /home/dwmw2/openssl-cvs/openssl/ssl/t1_enc.c,v retrieving revision 1.35.2.3 diff -u -p -r1.35.2.3 t1_enc.c --- ssl/t1_enc.c16 Feb 2007 20:40:07 - 1.35.2.3 +++ ssl/t1_enc.c28 Sep 2008 23:43:45 - @@ -738,8 +738,8 @@ int tls1_mac(SSL *ssl, unsigned char *md md_size=EVP_MD_size(hash); buf[0]=rec-type; - buf[1]=TLS1_VERSION_MAJOR; - buf[2]=TLS1_VERSION_MINOR; + buf[1]=(unsigned char)(ssl-version 8); + buf[2]=(unsigned char)(ssl-version 0xff); buf[3]=rec-length8; buf[4]=rec-length0xff; -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: DTLS clue requested.
On Tue, 2008-09-23 at 23:12 -0700, nagendra modadugu wrote: Hi David, unfortunately I've been out of touch with the developments to DTLS for some time. I forwarded your message to Eric Rescorla who worked with Cisco to get their implementation working. Thanks. I suspect that Cisco has proprietary patches that they haven't disclosed (or don't know how to). Hm, I was hoping that it wasn't any deliberate proprietary patches, but rather just an incompatibility because they were using a pre-RFC snapshot of the protocol. Why use a standard protocol but then hack it up with extra proprietary nonsense? At the worst, I should be able to reverse-engineer the library I have. Most functions will be identical, and once I have it down to a list of known-different functions I can take a closer look at each one. Armed with the unmodified source code and a disassembler it shouldn't be particularly hard to work out the differences. But that's a pain, especially as I'm mostly clueless about the protocol so wouldn't be able to make many educated guesses -- it'd all be brainless grunt-work. So far, I've noticed that their library is calling tls1_change_cipher_state() for a second time during my test case (both after receiving the Server Hello, while the real OpenSSL only does so once. [EMAIL PROTECTED] anyconnect]$ LD_LIBRARY_PATH=. ./dtls-test Found AES128-SHA cipher at 28 SSL_SESSION is 200 bytes EVP_CipherInit_ex 0x980d5f0 0x27e7a0 (nid 1a3) (nil) 0x980d5b8 0x980d5d8 0 Key:: 0b 33 d2 ef 9a 99 d6 d5 01 0f c5 83 6c 2f 8b 49 IV:: d0 8f 1f 6b 5f 20 28 9a 99 e8 2c 88 c8 41 78 bf EVP_CipherInit_ex 0x980d778 0x27e7a0 (nid 1a3) (nil) 0x980d5a8 0x980d5c8 2 Key:: cf f5 ef f9 fe f9 09 af 7b b9 8b df 11 1e 23 14 IV:: 9e 73 c8 be 5a 93 fc ad b5 37 c1 11 eb d0 fa 65 Success Child done. [EMAIL PROTECTED] anyconnect]$ LD_LIBRARY_PATH=/home/dwmw2/working/openssl-0.9.8e ./dtls-test Found AES128-SHA cipher at 29 SSL_SESSION is 200 bytes EVP_CipherInit_ex 0x8df2640 0x2957a0 (nid 1a3) (nil) 0x8df2608 0x8df2628 0 Key:: 0b 33 d2 ef 9a 99 d6 d5 01 0f c5 83 6c 2f 8b 49 IV:: d0 8f 1f 6b 5f 20 28 9a 99 e8 2c 88 c8 41 78 bf Child done. DTLS connection returned 0 13867:error:14101119:SSL routines:DTLS1_PROCESS_RECORD:decryption failed or bad record mac:d1_pkt.c:466: -- dwmw2 __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
DTLS clue requested.
I'm working on a VPN client compatible with Cisco's AnyConnect, which uses SSL + DTLS. My code so far is at git:// or http://git.infradead.org/users/dwmw2/anyconnect.git It's mostly going quite well, but I'm having trouble with DTLS compatibility and would massively appreciate some help from someone a little more clueful about DTLS. I can only actually get a successful handshake with their server when I use the libssl.so.0.9.8 which is shipped as part Cisco's own client -- I can't get it working with any version of OpenSSL that I build myself. My library always rejects the ServerHello packet: 12293:error:14101119:SSL routines:DTLS1_PROCESS_RECORD:decryption failed or bad record mac:d1_pkt.c:466: Their library seems to be (contains the strings): OpenSSL 0.9.8f 11 Oct 2007 However, the traffic I see on the wire is the pre-RFC version of DTLS (DTLS1_BAD_VER). But OpenSSL 0.9.8f postdates RFC4347 and had already been updated to the official protocol version number -- so whatever they're shipping, it's certainly not a pristine OpenSSL 0.9.8f. I've tried using the last release of OpenSSL which actually supported that version of the DTLS protocol (0.9.8e), and I've tried 0.9.8f and newer versions. None of them work. The only thing that works is using LD_LIBRARY_PATH to run my client against _their_ build of the library. I suspect that they haven't done anything particularly _exciting_ in their version of the library -- they've probably just reverted some of the updates in 0.9.8f which change to the the new behaviour defined in RFC4347. And maybe back-ported some later bug fixes. I've tried starting with 0.9.8f and reverting individual changes to see if I could get it to work, and I've tried some intermediate points between 0.9.8e and 0.9.8f, but haven't really had much luck and I'm mostly clueless about the details -- I would really appreciate some input from someone who actually knows the protocol a little better. I'm kind of hoping it's immediately obvious to someone. Although their own client uses the old version (DTLS1_BAD_VER) of the protocol, their server does actually seem to respond to the new version too. Its responses are slightly different (two extra bytes) according to whether I use DTLS1_BAD_VER or DTLS1_VERSION, so it does seem to be adapting to what the client sends rather than just echoing the version number. But the ultimate result in both cases is exactly the same. I send a Client Hello, get a Hello Verify Request. I send the Client Hello again, get a Server Hello. And then I send a 'Bad Record MAC' alert and the connection is over. I've made a simple test case, by capturing the traffic during a _failed_ session with OpenSSL-0.9.8e. The captured packets _work_ when I play them back against their library, but obviously fail when run against my build of OpenSSL-0.9.8e. This capture is using DTLS1_BAD_VER, of course. I _could_ do a capture using a newer version of OpenSSL and thus with DTLS1_VERSION, but the server side of that might be broken anyway -- I have no reason to believe there are _any_ working clients using that version of the protocol. And I wouldn't be able to show that test case working, either. So I think it's best to work with the old version of the protocol to start with, and work out what's going on. The test program is at http://david.woodhou.se/dtls-test.c and also below, and their version of libssl.so.0.9.8 is next to it on the web server (sha1 21a5704ea4f66dd48ea2b9d6c5b8ab85d4e16d89). [EMAIL PROTECTED] anyconnect]$ LD_LIBRARY_PATH=/opt/cisco/vpn/lib ./dtls-test Found AES128-SHA cipher at 28 SSL_SESSION is 200 bytes Child done. Success [EMAIL PROTECTED] anyconnect]$ LD_LIBRARY_PATH=/home/dwmw2/working/openssl-0.9.8e ./dtls-test Found AES128-SHA cipher at 29 SSL_SESSION is 200 bytes ... lots of debugging that I added, which didn't enlighten me at all ... DTLS connection returned 0 12994:error:14101119:SSL routines:DTLS1_PROCESS_RECORD:decryption failed or bad record mac:d1_pkt.c:466: Child done. This is the test case /* * Open AnyConnect (SSL + DTLS) client * * © 2008 David Woodhouse [EMAIL PROTECTED] * * Permission to use, copy, modify, and/or distribute this software * for any purpose with or without fee is hereby granted, provided * that the above copyright notice and this permission notice appear * in all copies. * * THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include errno.h #include sys/types.h #include sys/socket.h #include netdb.h #include unistd.h #include openssl