Re: Use TLS over UDP connection

2013-02-25 Thread David Woodhouse
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

2010-08-31 Thread David Woodhouse
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

2010-08-26 Thread David Woodhouse
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?)

2010-06-07 Thread David Woodhouse
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?)

2010-06-03 Thread David Woodhouse
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

2010-05-11 Thread David Woodhouse
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

2010-05-11 Thread David Woodhouse
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.

2010-05-09 Thread David Woodhouse
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.

2010-05-07 Thread David Woodhouse
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.

2010-05-07 Thread David Woodhouse
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

2010-04-08 Thread David Woodhouse
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?

2010-04-07 Thread David Woodhouse
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?

2010-04-07 Thread David Woodhouse
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

2010-03-28 Thread David Woodhouse
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

2010-03-23 Thread David Woodhouse
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.

2009-06-04 Thread David Woodhouse
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.

2009-06-03 Thread David Woodhouse
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.

2009-06-03 Thread David Woodhouse
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.

2009-06-02 Thread David Woodhouse
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.

2009-06-02 Thread David Woodhouse
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.

2009-05-31 Thread David Woodhouse
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.

2009-05-31 Thread David Woodhouse
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.

2009-05-22 Thread David Woodhouse
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.

2009-05-21 Thread David Woodhouse
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

2009-01-24 Thread David Woodhouse
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

2009-01-24 Thread David Woodhouse
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

2009-01-21 Thread David Woodhouse
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

2008-09-28 Thread David Woodhouse
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

2008-09-28 Thread David Woodhouse
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.

2008-09-26 Thread David Woodhouse
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.

2008-09-23 Thread David Woodhouse
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