Commit 6dbb6219 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Make tls1_check_chain return a set of flags indicating checks passed

by a certificate chain. Add additional tests to handle client
certificates: checks for matching certificate type and issuer name
comparison.

Print out results of checks for each candidate chain tested in
s_server/s_client.
parent ec4a50b3
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -4,6 +4,12 @@


 Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]
 Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]


  *) Make tls1_check_chain return a set of flags indicating checks passed
     by a certificate chain. Add additional tests to handle client
     certificates: checks for matching certificate type and issuer name
     comparison.
     [Steve Henson]

  *) If an attempt is made to use a signature algorithm not in the peer
  *) If an attempt is made to use a signature algorithm not in the peer
     preference list abort the handshake. If client has no suitable
     preference list abort the handshake. If client has no suitable
     signature algorithms in response to a certificate request do not
     signature algorithms in response to a certificate request do not
+45 −2
Original line number Original line Diff line number Diff line
@@ -1134,12 +1134,45 @@ struct ssl_excert_st
	struct ssl_excert_st *next, *prev;
	struct ssl_excert_st *next, *prev;
	};
	};


struct chain_flags
	{
	int flag;
	const char *name;
	};

struct chain_flags chain_flags_list[] =
	{
		{CERT_PKEY_VALID, "Overall Validity"},
		{CERT_PKEY_SIGN,  "Sign with EE key"},
		{CERT_PKEY_EE_SIGNATURE, "EE signature"},
		{CERT_PKEY_CA_SIGNATURE, "CA signature"},
		{CERT_PKEY_EE_PARAM, "EE key parameters"},
		{CERT_PKEY_CA_PARAM, "CA key parameters"},
		{CERT_PKEY_EXPLICIT_SIGN,  "Explicity sign with EE key"},
		{CERT_PKEY_ISSUER_NAME,  "Issuer Name"},
		{CERT_PKEY_CERT_TYPE,  "Certificate Type"},
		{0, NULL}
	};


static void print_chain_flags(BIO *out, int flags)
	{
	struct chain_flags *ctmp = chain_flags_list;
	while(ctmp->name)
		{
		BIO_printf(out, "\t%s: %s\n", ctmp->name,
				flags & ctmp->flag ? "OK" : "NOT OK");
		ctmp++;
		}
	}

/* Very basic selection callback: just use any certificate chain
/* Very basic selection callback: just use any certificate chain
 * reported as valid. More sophisticated could prioritise according
 * reported as valid. More sophisticated could prioritise according
 * to local policy.
 * to local policy.
 */
 */
static int set_cert_cb(SSL *ssl, void *arg)
static int set_cert_cb(SSL *ssl, void *arg)
	{
	{
	int i, rv;
	SSL_EXCERT *exc = arg;
	SSL_EXCERT *exc = arg;
	SSL_certs_clear(ssl);
	SSL_certs_clear(ssl);


@@ -1152,9 +1185,19 @@ static int set_cert_cb(SSL *ssl, void *arg)
	while (exc->next)
	while (exc->next)
		exc = exc->next;
		exc = exc->next;


	i = 0;	

	while(exc)
	while(exc)
		{
		{
		if (SSL_check_chain(ssl, exc->cert, exc->key, exc->chain))
		i++;
		rv = SSL_check_chain(ssl, exc->cert, exc->key, exc->chain);
		BIO_printf(bio_err, "Checking cert chain %d:\nSubject: ", i);
		X509_NAME_print_ex(bio_err, X509_get_subject_name(exc->cert), 0,
							XN_FLAG_ONELINE);
		BIO_puts(bio_err, "\n");
		
		print_chain_flags(bio_err, rv);
		if (rv & CERT_PKEY_VALID)
			{
			{
			SSL_use_certificate(ssl, exc->cert);
			SSL_use_certificate(ssl, exc->cert);
			SSL_use_PrivateKey(ssl, exc->key);
			SSL_use_PrivateKey(ssl, exc->key);
+6 −0
Original line number Original line Diff line number Diff line
@@ -1963,6 +1963,12 @@ int ssl3_get_certificate_request(SSL *s)
			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_DATA_LENGTH_TOO_LONG);
			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_DATA_LENGTH_TOO_LONG);
			goto err;
			goto err;
			}
			}
		/* Clear certificate digests and validity flags */
		for (i = 0; i < SSL_PKEY_NUM; i++)
			{
			s->cert->pkeys[i].digest = NULL;
			s->cert->pkeys[i].valid_flags = 0;
			}
		if ((llen & 1) || !tls1_process_sigalgs(s, p, llen))
		if ((llen & 1) || !tls1_process_sigalgs(s, p, llen))
			{
			{
			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+20 −0
Original line number Original line Diff line number Diff line
@@ -662,6 +662,26 @@ struct ssl_session_st
/* Con't include root CA in chain */
/* Con't include root CA in chain */
#define SSL_BUILD_CHAIN_FLAG_NO_ROOT	0x2
#define SSL_BUILD_CHAIN_FLAG_NO_ROOT	0x2


/* Flags returned by SSL_check_chain */
/* Certificate can be used with this session */
#define CERT_PKEY_VALID		0x1
/* Certificate can also be used for signing */
#define CERT_PKEY_SIGN		0x2
/* EE certificate signing algorithm OK */
#define CERT_PKEY_EE_SIGNATURE	0x10
/* CA signature algorithms OK */
#define CERT_PKEY_CA_SIGNATURE	0x20
/* EE certificate parameters OK */
#define CERT_PKEY_EE_PARAM	0x40
/* CA certificate parameters OK */
#define CERT_PKEY_CA_PARAM	0x80
/* Signing explicitly allowed as opposed to SHA1 fallback */
#define CERT_PKEY_EXPLICIT_SIGN	0x100
/* Client CA issuer names match (always set for server cert) */
#define CERT_PKEY_ISSUER_NAME	0x200
/* Cert type matches client types (always set for server cert) */
#define CERT_PKEY_CERT_TYPE	0x400

/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
 * they cannot be used to clear bits. */
 * they cannot be used to clear bits. */


+2 −1
Original line number Original line Diff line number Diff line
@@ -467,7 +467,8 @@ void ssl_cert_clear_certs(CERT *c)
                if (cpk->authz != NULL)
                if (cpk->authz != NULL)
			OPENSSL_free(cpk->authz);
			OPENSSL_free(cpk->authz);
#endif
#endif
		cpk->valid_flags = 0;
		/* Clear all flags apart from explicit sign */
		cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
		}
		}
	}
	}


Loading