Until now, key selection was based on tls_client_certificate_type_t and now
uses a simple mapping from these types to tls_signature_scheme_t.
- * Find a private key suitable to sign Certificate Verify
+ * Convert certificate types to signature schemes so TLS version <= 1.1 can use
+ * the same private key enumeration as newer TLS versions.
-static private_key_t *find_private_key(private_tls_peer_t *this)
+static void convert_cert_types(private_tls_peer_t *this)
- private_key_t *key = NULL;
- key_type_t type;
- uint8_t cert;
+ bio_writer_t *writer;
+ uint8_t type;
- if (!this->peer)
- {
- return NULL;
- }
reader = bio_reader_create(this->cert_types);
reader = bio_reader_create(this->cert_types);
- while (reader->remaining(reader) && reader->read_uint8(reader, &cert))
+ writer = bio_writer_create(0);
+ while (reader->remaining(reader) && reader->read_uint8(reader, &type))
+ /* each certificate type is mapped to one signature scheme, which is not
+ * ideal but serves our needs in legacy TLS versions */
+ switch (type)
+ writer->write_uint16(writer, TLS_SIG_RSA_PKCS1_SHA256);
break;
case TLS_ECDSA_SIGN:
break;
case TLS_ECDSA_SIGN:
+ writer->write_uint16(writer, TLS_SIG_ECDSA_SHA256);
break;
default:
continue;
}
break;
default:
continue;
}
- key = lib->credmgr->get_private(lib->credmgr, type,
- this->peer, this->peer_auth);
- if (key)
- {
- break;
- }
}
reader->destroy(reader);
}
reader->destroy(reader);
+ this->hashsig = writer->extract_buf(writer);
+ writer->destroy(writer);
version_min = this->tls->get_version_min(this->tls);
version_max = this->tls->get_version_max(this->tls);
version_min = this->tls->get_version_min(this->tls);
version_max = this->tls->get_version_max(this->tls);
- if (version_max > TLS_1_1)
+ if (!this->hashsig.len)
+ {
+ convert_cert_types(this);
+ }
+ enumerator = tls_create_private_key_enumerator(version_min, version_max,
+ this->hashsig, this->peer);
+ if (!enumerator || !enumerator->enumerate(enumerator, &key, &auth))
- enumerator = tls_create_private_key_enumerator(version_min, version_max,
- this->hashsig, this->peer);
if (!enumerator)
{
DBG1(DBG_TLS, "no common signature algorithms found");
if (!enumerator)
{
DBG1(DBG_TLS, "no common signature algorithms found");
- if (enumerator->enumerate(enumerator, &key, &auth))
- this->private = key->get_ref(key);
- this->peer_auth->merge(this->peer_auth, auth, FALSE);
+ DBG1(DBG_TLS, "no usable TLS client certificate found for '%Y'",
+ this->peer);
- enumerator->destroy(enumerator);
+ this->peer->destroy(this->peer);
+ this->peer = NULL;
- this->private = find_private_key(this);
- }
- if (!this->private)
- {
- DBG1(DBG_TLS, "no usable TLS client certificate found for '%Y'",
- this->peer);
- this->peer->destroy(this->peer);
- this->peer = NULL;
+ this->private = key->get_ref(key);
+ this->peer_auth->merge(this->peer_auth, auth, FALSE);
+ DESTROY_IF(enumerator);
/* generate certificate payload */
certs = bio_writer_create(256);
/* generate certificate payload */
certs = bio_writer_create(256);