New ctrls to retrieve supported signature algorithms and curves and
extensions to s_client and s_server to print out retrieved valued.

Extend CERT structure to cache supported signature algorithm data.
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index db79a99..248bb94 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3365,6 +3365,32 @@
 		else
 			return ssl_cert_add0_chain_cert(s->cert, (X509 *)parg);
 
+	case SSL_CTRL_GET_CURVELIST:
+		{
+		unsigned char *clist;
+		size_t clistlen;
+		if (!s->session)
+			return 0;
+		clist = s->session->tlsext_ellipticcurvelist;
+		clistlen = s->session->tlsext_ellipticcurvelist_length / 2;
+		if (parg)
+			{
+			size_t i;
+			int *cptr = parg;
+			unsigned int cid, nid;
+			for (i = 0; i < clistlen; i++)
+				{
+				n2s(clist, cid);
+				nid = tls1_ec_curve_id2nid(cid);
+				if (nid != 0)
+					cptr[i] = nid;
+				else
+					cptr[i] = TLSEXT_nid_unknown | cid;
+				}
+			}
+		return (int)clistlen;
+		}
+
 	default:
 		break;
 		}
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 8998e9a..3e255fc 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -366,6 +366,7 @@
 typedef struct ssl_method_st SSL_METHOD;
 typedef struct ssl_cipher_st SSL_CIPHER;
 typedef struct ssl_session_st SSL_SESSION;
+typedef struct tls_sigalgs_st TLS_SIGALGS;
 
 DECLARE_STACK_OF(SSL_CIPHER)
 
@@ -1617,6 +1618,8 @@
 #define SSL_CTRL_CHAIN				88
 #define SSL_CTRL_CHAIN_CERT			89
 
+#define SSL_CTRL_GET_CURVELIST			90
+
 #define DTLSv1_get_timeout(ssl, arg) \
 	SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
 #define DTLSv1_handle_timeout(ssl) \
@@ -1675,6 +1678,9 @@
 	SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
 #define SSL_add1_chain_cert(ctx,x509) \
 	SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
+#define SSL_get1_curvelist(ctx, s) \
+	SSL_ctrl(ctx,SSL_CTRL_GET_CURVELIST,0,(char *)s)
+
 
 #ifndef OPENSSL_NO_BIO
 BIO_METHOD *BIO_f_ssl(void);
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index c48aa20..6a1c484 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -339,6 +339,9 @@
 	 * will be set during handshake.
 	 */
 	ssl_cert_set_default_md(ret);
+	/* Sigalgs set to NULL as we get these from handshake too */
+	ret->sigalgs = NULL;
+	ret->sigalgslen = 0;
 
 	return(ret);
 	
@@ -418,6 +421,8 @@
 			EVP_PKEY_free(c->pkeys[i].publickey);
 #endif
 		}
+	if (c->sigalgs)
+		OPENSSL_free(c->sigalgs);
 	OPENSSL_free(c);
 	}
 
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index bdaca8b..ad5dc71 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -506,6 +506,11 @@
 
 	CERT_PKEY pkeys[SSL_PKEY_NUM];
 
+	/* Array of pairs of NIDs for signature algorithm extension */
+	TLS_SIGALGS *sigalgs;
+	/* Size of above array */
+	size_t sigalgslen;
+
 	int references; /* >1 only if SSL_copy_session_id is used */
 	} CERT;
 
@@ -534,7 +539,19 @@
 
 	int references; /* actually always 1 at the moment */
 	} SESS_CERT;
-
+/* Structure containing decoded values of signature algorithms extension */
+struct tls_sigalgs_st
+	{
+	/* NID of hash algorithm */
+	int hash_nid;
+	/* NID of signature algorithm */
+	int sign_nid;
+	/* Combined hash and signature NID */
+	int signandhash_nid;
+	/* Raw values used in extension */
+	unsigned char rsign;
+	unsigned char rhash;
+	};
 
 /*#define MAC_DEBUG	*/
 
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 9c76da1..dfd397f 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -2241,32 +2241,18 @@
 	} tls12_lookup;
 
 static tls12_lookup tls12_md[] = {
-#ifndef OPENSSL_NO_MD5
 	{NID_md5, TLSEXT_hash_md5},
-#endif
-#ifndef OPENSSL_NO_SHA
 	{NID_sha1, TLSEXT_hash_sha1},
-#endif
-#ifndef OPENSSL_NO_SHA256
 	{NID_sha224, TLSEXT_hash_sha224},
 	{NID_sha256, TLSEXT_hash_sha256},
-#endif
-#ifndef OPENSSL_NO_SHA512
 	{NID_sha384, TLSEXT_hash_sha384},
 	{NID_sha512, TLSEXT_hash_sha512}
-#endif
 };
 
 static tls12_lookup tls12_sig[] = {
-#ifndef OPENSSL_NO_RSA
 	{EVP_PKEY_RSA, TLSEXT_signature_rsa},
-#endif
-#ifndef OPENSSL_NO_RSA
 	{EVP_PKEY_DSA, TLSEXT_signature_dsa},
-#endif
-#ifndef OPENSSL_NO_ECDSA
 	{EVP_PKEY_EC, TLSEXT_signature_ecdsa}
-#endif
 };
 
 static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
@@ -2279,18 +2265,17 @@
 		}
 	return -1;
 	}
-#if 0
+
 static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
 	{
 	size_t i;
 	for (i = 0; i < tlen; i++)
 		{
-		if (table[i].id == id)
+		if ((table[i].id) == id)
 			return table[i].nid;
 		}
-	return -1;
+	return NID_undef;
 	}
-#endif
 
 int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md)
 	{
@@ -2358,6 +2343,7 @@
 	int i, idx;
 	const EVP_MD *md;
 	CERT *c = s->cert;
+	TLS_SIGALGS *sigptr;
 	/* Extension ignored for TLS versions below 1.2 */
 	if (TLS1_get_version(s) < TLS1_2_VERSION)
 		return 1;
@@ -2370,11 +2356,26 @@
 	c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL;
 	c->pkeys[SSL_PKEY_ECC].digest = NULL;
 
-	for (i = 0; i < dsize; i += 2)
-		{
-		unsigned char hash_alg = data[i], sig_alg = data[i+1];
+	if (c->sigalgs)
+		OPENSSL_free(c->sigalgs);
+	c->sigalgs = OPENSSL_malloc((dsize/2) * sizeof(TLS_SIGALGS));
+	if (!c->sigalgs)
+		return 0;
+	c->sigalgslen = dsize/2;
 
-		switch(sig_alg)
+	for (i = 0, sigptr = c->sigalgs; i < dsize; i += 2, sigptr++)
+		{
+		sigptr->rhash = data[i];
+		sigptr->rsign = data[i + 1];
+		sigptr->hash_nid = tls12_find_nid(sigptr->rhash, tls12_md,
+					sizeof(tls12_md)/sizeof(tls12_lookup));
+		sigptr->sign_nid = tls12_find_nid(sigptr->rsign, tls12_sig,
+					sizeof(tls12_sig)/sizeof(tls12_lookup));
+		if (!OBJ_find_sigid_by_algs(&sigptr->signandhash_nid,
+						sigptr->hash_nid,
+						sigptr->sign_nid))
+			sigptr->signandhash_nid = NID_undef;
+		switch(sigptr->rsign)
 			{
 #ifndef OPENSSL_NO_RSA
 			case TLSEXT_signature_rsa:
@@ -2397,7 +2398,7 @@
 
 		if (c->pkeys[idx].digest == NULL)
 			{
-			md = tls12_get_hash(hash_alg);
+			md = tls12_get_hash(sigptr->rhash);
 			if (md)
 				{
 				c->pkeys[idx].digest = md;
@@ -2432,6 +2433,33 @@
 
 #endif
 
+int SSL_get_sigalgs(SSL *s, int idx,
+			int *psign, int *phash, int *psignandhash,
+			unsigned char *rsig, unsigned char *rhash)
+	{
+	if (s->cert->sigalgs == NULL)
+		return 0;
+	if (idx >= 0)
+		{
+		TLS_SIGALGS *psig;
+		if (idx >= (int)s->cert->sigalgslen)
+			return 0;
+		psig = s->cert->sigalgs + idx;
+		if (psign)
+			*psign = psig->sign_nid;
+		if (phash)
+			*phash = psig->hash_nid;
+		if (psignandhash)
+			*psignandhash = psig->signandhash_nid;
+		if (rsig)
+			*rsig = psig->rsign;
+		if (rhash)
+			*rhash = psig->rhash;
+		}
+	return s->cert->sigalgslen;
+	}
+	
+
 #ifndef OPENSSL_NO_HEARTBEATS
 int
 tls1_process_heartbeat(SSL *s)
diff --git a/ssl/tls1.h b/ssl/tls1.h
index c5e3a70..cca04b8 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -252,6 +252,8 @@
 #define TLSEXT_hash_sha256				4
 #define TLSEXT_hash_sha384				5
 #define TLSEXT_hash_sha512				6
+/* Flag set for unrecognised algorithms */
+#define TLSEXT_nid_unknown				0x1000000
 
 /* ExtensionType value from RFC5764 */
 #define TLSEXT_TYPE_use_srtp                           14
@@ -276,6 +278,10 @@
 	const char *label, size_t llen, const unsigned char *p, size_t plen,
 	int use_context);
 
+int SSL_get_sigalgs(SSL *s, int idx,
+			int *psign, int *phash, int *psignandhash,
+			unsigned char *rsig, unsigned char *rhash);
+
 #define SSL_set_tlsext_host_name(s,name) \
 SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)