Added generic TLS data sign/verify, hash/sig algorithm construction
This commit is contained in:
+108
-38
@@ -624,6 +624,55 @@ METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(tls_crypto_t, get_signature_algorithms, void,
|
||||||
|
private_tls_crypto_t *this, tls_writer_t *writer)
|
||||||
|
{
|
||||||
|
tls_writer_t *supported;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
hash_algorithm_t alg;
|
||||||
|
tls_hash_algorithm_t hash;
|
||||||
|
|
||||||
|
supported = tls_writer_create(32);
|
||||||
|
enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
|
||||||
|
while (enumerator->enumerate(enumerator, &alg))
|
||||||
|
{
|
||||||
|
switch (alg)
|
||||||
|
{
|
||||||
|
case HASH_MD5:
|
||||||
|
hash = TLS_HASH_MD5;
|
||||||
|
break;
|
||||||
|
case HASH_SHA1:
|
||||||
|
hash = TLS_HASH_SHA1;
|
||||||
|
break;
|
||||||
|
case HASH_SHA224:
|
||||||
|
hash = TLS_HASH_SHA224;
|
||||||
|
break;
|
||||||
|
case HASH_SHA256:
|
||||||
|
hash = TLS_HASH_SHA256;
|
||||||
|
break;
|
||||||
|
case HASH_SHA384:
|
||||||
|
hash = TLS_HASH_SHA384;
|
||||||
|
break;
|
||||||
|
case HASH_SHA512:
|
||||||
|
hash = TLS_HASH_SHA512;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
supported->write_uint8(supported, hash);
|
||||||
|
supported->write_uint8(supported, TLS_SIG_RSA);
|
||||||
|
if (alg != HASH_MD5 && alg != HASH_SHA224)
|
||||||
|
{
|
||||||
|
supported->write_uint8(supported, hash);
|
||||||
|
supported->write_uint8(supported, TLS_SIG_ECDSA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
writer->write_data16(writer, supported->get_buf(supported));
|
||||||
|
supported->destroy(supported);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tls_crypto_t, set_protection, void,
|
METHOD(tls_crypto_t, set_protection, void,
|
||||||
private_tls_crypto_t *this, tls_protection_t *protection)
|
private_tls_crypto_t *this, tls_protection_t *protection)
|
||||||
{
|
{
|
||||||
@@ -642,9 +691,9 @@ METHOD(tls_crypto_t, append_handshake, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a hash of the stored handshake data
|
* Create a hash using the suites HASH algorithm
|
||||||
*/
|
*/
|
||||||
static bool hash_handshake(private_tls_crypto_t *this, chunk_t *hash)
|
static bool hash_data(private_tls_crypto_t *this, chunk_t data, chunk_t *hash)
|
||||||
{
|
{
|
||||||
if (this->tls->get_version(this->tls) >= TLS_1_2)
|
if (this->tls->get_version(this->tls) >= TLS_1_2)
|
||||||
{
|
{
|
||||||
@@ -662,7 +711,7 @@ static bool hash_handshake(private_tls_crypto_t *this, chunk_t *hash)
|
|||||||
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, alg->hash);
|
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, alg->hash);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
hasher->allocate_hash(hasher, this->handshake, hash);
|
hasher->allocate_hash(hasher, data, hash);
|
||||||
hasher->destroy(hasher);
|
hasher->destroy(hasher);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -676,7 +725,7 @@ static bool hash_handshake(private_tls_crypto_t *this, chunk_t *hash)
|
|||||||
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_MD5);
|
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_MD5);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
md5->get_hash(md5, this->handshake, buf);
|
md5->get_hash(md5, data, buf);
|
||||||
md5->destroy(md5);
|
md5->destroy(md5);
|
||||||
sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||||
if (!sha1)
|
if (!sha1)
|
||||||
@@ -684,7 +733,7 @@ static bool hash_handshake(private_tls_crypto_t *this, chunk_t *hash)
|
|||||||
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_SHA1);
|
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_SHA1);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
sha1->get_hash(sha1, this->handshake, buf + HASH_SIZE_MD5);
|
sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5);
|
||||||
sha1->destroy(sha1);
|
sha1->destroy(sha1);
|
||||||
|
|
||||||
*hash = chunk_clone(chunk_from_thing(buf));
|
*hash = chunk_clone(chunk_from_thing(buf));
|
||||||
@@ -745,9 +794,9 @@ static signature_scheme_t hashsig_to_scheme(key_type_t type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tls_crypto_t, sign_handshake, bool,
|
METHOD(tls_crypto_t, sign, bool,
|
||||||
private_tls_crypto_t *this, private_key_t *key, tls_writer_t *writer,
|
private_tls_crypto_t *this, private_key_t *key, tls_writer_t *writer,
|
||||||
chunk_t hashsig)
|
chunk_t data, chunk_t hashsig)
|
||||||
{
|
{
|
||||||
if (this->tls->get_version(this->tls) >= TLS_1_2)
|
if (this->tls->get_version(this->tls) >= TLS_1_2)
|
||||||
{
|
{
|
||||||
@@ -757,6 +806,11 @@ METHOD(tls_crypto_t, sign_handshake, bool,
|
|||||||
chunk_t sig;
|
chunk_t sig;
|
||||||
bool done = FALSE;
|
bool done = FALSE;
|
||||||
|
|
||||||
|
if (!hashsig.len)
|
||||||
|
{ /* fallback if none given */
|
||||||
|
hashsig = chunk_from_chars(
|
||||||
|
TLS_HASH_SHA1, TLS_SIG_RSA, TLS_HASH_SHA1, TLS_SIG_ECDSA);
|
||||||
|
}
|
||||||
reader = tls_reader_create(hashsig);
|
reader = tls_reader_create(hashsig);
|
||||||
while (reader->remaining(reader) >= 2)
|
while (reader->remaining(reader) >= 2)
|
||||||
{
|
{
|
||||||
@@ -765,7 +819,7 @@ METHOD(tls_crypto_t, sign_handshake, bool,
|
|||||||
{
|
{
|
||||||
scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
|
scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
|
||||||
if (scheme != SIGN_UNKNOWN &&
|
if (scheme != SIGN_UNKNOWN &&
|
||||||
key->sign(key, scheme, this->handshake, &sig))
|
key->sign(key, scheme, data, &sig))
|
||||||
{
|
{
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -778,7 +832,7 @@ METHOD(tls_crypto_t, sign_handshake, bool,
|
|||||||
DBG1(DBG_TLS, "none of the proposed hash/sig algorithms supported");
|
DBG1(DBG_TLS, "none of the proposed hash/sig algorithms supported");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
DBG2(DBG_TLS, "signed handshake data with %N/%N",
|
DBG2(DBG_TLS, "created signature with %N/%N",
|
||||||
tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
|
tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
|
||||||
writer->write_uint8(writer, hash);
|
writer->write_uint8(writer, hash);
|
||||||
writer->write_uint8(writer, alg);
|
writer->write_uint8(writer, alg);
|
||||||
@@ -788,29 +842,29 @@ METHOD(tls_crypto_t, sign_handshake, bool,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
chunk_t sig, hash;
|
chunk_t sig, hash;
|
||||||
|
bool done;
|
||||||
|
|
||||||
switch (key->get_type(key))
|
switch (key->get_type(key))
|
||||||
{
|
{
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
if (!hash_handshake(this, &hash))
|
if (!hash_data(this, data, &hash))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, &sig))
|
done = key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, &sig);
|
||||||
{
|
|
||||||
free(hash.ptr);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
DBG2(DBG_TLS, "signed handshake data with SHA1+MD5/RSA");
|
|
||||||
free(hash.ptr);
|
free(hash.ptr);
|
||||||
|
if (!done)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
DBG2(DBG_TLS, "created signature with MD5+SHA1/RSA");
|
||||||
break;
|
break;
|
||||||
case KEY_ECDSA:
|
case KEY_ECDSA:
|
||||||
if (!key->sign(key, SIGN_ECDSA_WITH_SHA1_DER,
|
if (!key->sign(key, SIGN_ECDSA_WITH_SHA1_DER, data, &sig))
|
||||||
this->handshake, &sig))
|
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
DBG2(DBG_TLS, "signed handshake data with SHA1/ECDSA");
|
DBG2(DBG_TLS, "created signature with SHA1/ECDSA");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -821,8 +875,9 @@ METHOD(tls_crypto_t, sign_handshake, bool,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tls_crypto_t, verify_handshake, bool,
|
METHOD(tls_crypto_t, verify, bool,
|
||||||
private_tls_crypto_t *this, public_key_t *key, tls_reader_t *reader)
|
private_tls_crypto_t *this, public_key_t *key, tls_reader_t *reader,
|
||||||
|
chunk_t data)
|
||||||
{
|
{
|
||||||
if (this->tls->get_version(this->tls) >= TLS_1_2)
|
if (this->tls->get_version(this->tls) >= TLS_1_2)
|
||||||
{
|
{
|
||||||
@@ -834,56 +889,55 @@ METHOD(tls_crypto_t, verify_handshake, bool,
|
|||||||
!reader->read_uint8(reader, &alg) ||
|
!reader->read_uint8(reader, &alg) ||
|
||||||
!reader->read_data16(reader, &sig))
|
!reader->read_data16(reader, &sig))
|
||||||
{
|
{
|
||||||
DBG1(DBG_TLS, "received invalid Certificate Verify");
|
DBG1(DBG_TLS, "received invalid signature");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
|
scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
|
||||||
if (scheme == SIGN_UNKNOWN)
|
if (scheme == SIGN_UNKNOWN)
|
||||||
{
|
{
|
||||||
DBG1(DBG_TLS, "Certificate Verify algorithms %N/%N not supported",
|
DBG1(DBG_TLS, "signature algorithms %N/%N not supported",
|
||||||
tls_hash_algorithm_names, hash,
|
tls_hash_algorithm_names, hash,
|
||||||
tls_signature_algorithm_names, alg);
|
tls_signature_algorithm_names, alg);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!key->verify(key, scheme, this->handshake, sig))
|
if (!key->verify(key, scheme, data, sig))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
DBG2(DBG_TLS, "verified handshake data with %N/%N",
|
DBG2(DBG_TLS, "verified signature with %N/%N",
|
||||||
tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
|
tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
chunk_t sig, hash;
|
chunk_t sig, hash;
|
||||||
|
bool done;
|
||||||
|
|
||||||
if (!reader->read_data16(reader, &sig))
|
if (!reader->read_data16(reader, &sig))
|
||||||
{
|
{
|
||||||
DBG1(DBG_TLS, "received invalid Certificate Verify");
|
DBG1(DBG_TLS, "received invalid signature");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
switch (key->get_type(key))
|
switch (key->get_type(key))
|
||||||
{
|
{
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
if (!hash_handshake(this, &hash))
|
if (!hash_data(this, data, &hash))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, sig))
|
done = key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, sig);
|
||||||
{
|
|
||||||
free(hash.ptr);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
DBG2(DBG_TLS, "verified handshake data with SHA1+MD5/RSA");
|
|
||||||
free(hash.ptr);
|
free(hash.ptr);
|
||||||
|
if (!done)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
DBG2(DBG_TLS, "verified signature data with MD5+SHA1/RSA");
|
||||||
break;
|
break;
|
||||||
case KEY_ECDSA:
|
case KEY_ECDSA:
|
||||||
if (!key->verify(key, SIGN_ECDSA_WITH_SHA1_DER,
|
if (!key->verify(key, SIGN_ECDSA_WITH_SHA1_DER, data, sig))
|
||||||
this->handshake, sig))
|
|
||||||
{
|
{
|
||||||
free(hash.ptr);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
DBG2(DBG_TLS, "verified handshake data with SHA1/ECDSA");
|
DBG2(DBG_TLS, "verified signature with SHA1/ECDSA");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -892,6 +946,19 @@ METHOD(tls_crypto_t, verify_handshake, bool,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(tls_crypto_t, sign_handshake, bool,
|
||||||
|
private_tls_crypto_t *this, private_key_t *key, tls_writer_t *writer,
|
||||||
|
chunk_t hashsig)
|
||||||
|
{
|
||||||
|
return sign(this, key, writer, this->handshake, hashsig);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(tls_crypto_t, verify_handshake, bool,
|
||||||
|
private_tls_crypto_t *this, public_key_t *key, tls_reader_t *reader)
|
||||||
|
{
|
||||||
|
return verify(this, key, reader, this->handshake);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tls_crypto_t, calculate_finished, bool,
|
METHOD(tls_crypto_t, calculate_finished, bool,
|
||||||
private_tls_crypto_t *this, char *label, char out[12])
|
private_tls_crypto_t *this, char *label, char out[12])
|
||||||
{
|
{
|
||||||
@@ -901,7 +968,7 @@ METHOD(tls_crypto_t, calculate_finished, bool,
|
|||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!hash_handshake(this, &seed))
|
if (!hash_data(this, this->handshake, &seed))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1062,8 +1129,11 @@ tls_crypto_t *tls_crypto_create(tls_t *tls)
|
|||||||
.public = {
|
.public = {
|
||||||
.get_cipher_suites = _get_cipher_suites,
|
.get_cipher_suites = _get_cipher_suites,
|
||||||
.select_cipher_suite = _select_cipher_suite,
|
.select_cipher_suite = _select_cipher_suite,
|
||||||
|
.get_signature_algorithms = _get_signature_algorithms,
|
||||||
.set_protection = _set_protection,
|
.set_protection = _set_protection,
|
||||||
.append_handshake = _append_handshake,
|
.append_handshake = _append_handshake,
|
||||||
|
.sign = _sign,
|
||||||
|
.verify = _verify,
|
||||||
.sign_handshake = _sign_handshake,
|
.sign_handshake = _sign_handshake,
|
||||||
.verify_handshake = _verify_handshake,
|
.verify_handshake = _verify_handshake,
|
||||||
.calculate_finished = _calculate_finished,
|
.calculate_finished = _calculate_finished,
|
||||||
|
|||||||
@@ -328,6 +328,13 @@ struct tls_crypto_t {
|
|||||||
tls_cipher_suite_t (*select_cipher_suite)(tls_crypto_t *this,
|
tls_cipher_suite_t (*select_cipher_suite)(tls_crypto_t *this,
|
||||||
tls_cipher_suite_t *suites, int count);
|
tls_cipher_suite_t *suites, int count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the list of supported hash/sig algorithms to writer.
|
||||||
|
*
|
||||||
|
* @param writer writer to write supported hash/sig algorithms
|
||||||
|
*/
|
||||||
|
void (*get_signature_algorithms)(tls_crypto_t *this, tls_writer_t *writer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the protection layer of the TLS stack to control it.
|
* Set the protection layer of the TLS stack to control it.
|
||||||
*
|
*
|
||||||
@@ -344,6 +351,29 @@ struct tls_crypto_t {
|
|||||||
void (*append_handshake)(tls_crypto_t *this,
|
void (*append_handshake)(tls_crypto_t *this,
|
||||||
tls_handshake_type_t type, chunk_t data);
|
tls_handshake_type_t type, chunk_t data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign a blob of data, append signature to writer.
|
||||||
|
*
|
||||||
|
* @param key private key to use for signature
|
||||||
|
* @param writer TLS writer to write signature to
|
||||||
|
* @param data data to sign
|
||||||
|
* @param hashsig list of TLS1.2 hash/sig algorithms to select from
|
||||||
|
* @return TRUE if signature create successfully
|
||||||
|
*/
|
||||||
|
bool (*sign)(tls_crypto_t *this, private_key_t *key,
|
||||||
|
tls_writer_t *writer, chunk_t data, chunk_t hashsig);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify a blob of data, read signature from a reader.
|
||||||
|
*
|
||||||
|
* @param key public key to verify signature with
|
||||||
|
* @param reader TLS reader to read signature from
|
||||||
|
* @param data data to verify signature
|
||||||
|
* @return TRUE if signature valid
|
||||||
|
*/
|
||||||
|
bool (*verify)(tls_crypto_t *this, public_key_t *key,
|
||||||
|
tls_reader_t *reader, chunk_t data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a signature of the handshake data using a given private key.
|
* Create a signature of the handshake data using a given private key.
|
||||||
*
|
*
|
||||||
|
|||||||
+9
-63
@@ -532,12 +532,16 @@ static status_t send_certificate(private_tls_server_t *this,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a list of supported certificate types and hash/sig algorithms
|
* Send Certificate Request
|
||||||
*/
|
*/
|
||||||
static void get_supported_algorithms(private_tls_server_t *this,
|
static status_t send_certificate_request(private_tls_server_t *this,
|
||||||
tls_writer_t *writer)
|
tls_handshake_type_t *type, tls_writer_t *writer)
|
||||||
{
|
{
|
||||||
tls_writer_t *supported;
|
tls_writer_t *authorities, *supported;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
certificate_t *cert;
|
||||||
|
x509_t *x509;
|
||||||
|
identification_t *id;
|
||||||
|
|
||||||
supported = tls_writer_create(4);
|
supported = tls_writer_create(4);
|
||||||
/* we propose both RSA and ECDSA */
|
/* we propose both RSA and ECDSA */
|
||||||
@@ -545,68 +549,10 @@ static void get_supported_algorithms(private_tls_server_t *this,
|
|||||||
supported->write_uint8(supported, TLS_ECDSA_SIGN);
|
supported->write_uint8(supported, TLS_ECDSA_SIGN);
|
||||||
writer->write_data8(writer, supported->get_buf(supported));
|
writer->write_data8(writer, supported->get_buf(supported));
|
||||||
supported->destroy(supported);
|
supported->destroy(supported);
|
||||||
|
|
||||||
if (this->tls->get_version(this->tls) >= TLS_1_2)
|
if (this->tls->get_version(this->tls) >= TLS_1_2)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
this->crypto->get_signature_algorithms(this->crypto, writer);
|
||||||
hash_algorithm_t alg;
|
|
||||||
tls_hash_algorithm_t hash;
|
|
||||||
|
|
||||||
supported = tls_writer_create(32);
|
|
||||||
enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
|
|
||||||
while (enumerator->enumerate(enumerator, &alg))
|
|
||||||
{
|
|
||||||
switch (alg)
|
|
||||||
{
|
|
||||||
case HASH_MD5:
|
|
||||||
hash = TLS_HASH_MD5;
|
|
||||||
break;
|
|
||||||
case HASH_SHA1:
|
|
||||||
hash = TLS_HASH_SHA1;
|
|
||||||
break;
|
|
||||||
case HASH_SHA224:
|
|
||||||
hash = TLS_HASH_SHA224;
|
|
||||||
break;
|
|
||||||
case HASH_SHA256:
|
|
||||||
hash = TLS_HASH_SHA256;
|
|
||||||
break;
|
|
||||||
case HASH_SHA384:
|
|
||||||
hash = TLS_HASH_SHA384;
|
|
||||||
break;
|
|
||||||
case HASH_SHA512:
|
|
||||||
hash = TLS_HASH_SHA512;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
supported->write_uint8(supported, hash);
|
|
||||||
supported->write_uint8(supported, TLS_SIG_RSA);
|
|
||||||
if (alg != HASH_MD5 && alg != HASH_SHA224)
|
|
||||||
{
|
|
||||||
supported->write_uint8(supported, hash);
|
|
||||||
supported->write_uint8(supported, TLS_SIG_ECDSA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
|
|
||||||
writer->write_data16(writer, supported->get_buf(supported));
|
|
||||||
supported->destroy(supported);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send Certificate Request
|
|
||||||
*/
|
|
||||||
static status_t send_certificate_request(private_tls_server_t *this,
|
|
||||||
tls_handshake_type_t *type, tls_writer_t *writer)
|
|
||||||
{
|
|
||||||
tls_writer_t *authorities;
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
certificate_t *cert;
|
|
||||||
x509_t *x509;
|
|
||||||
identification_t *id;
|
|
||||||
|
|
||||||
get_supported_algorithms(this, writer);
|
|
||||||
|
|
||||||
authorities = tls_writer_create(64);
|
authorities = tls_writer_create(64);
|
||||||
enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
|
enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
|
||||||
|
|||||||
Reference in New Issue
Block a user