eduardsui / tlse

Single C file TLS 1.2/1.3 implementation, using tomcrypt as crypto library
Other
535 stars 87 forks source link

Is there a building certificate verify handshake interface on the client side? #50

Closed starrysec closed 3 years ago

starrysec commented 5 years ago

I use a client certificate, but the handshake process does not have a certificate verify process. I can't find building certificate verify interface?

starrysec commented 5 years ago

I added a function for client to build certificate verify message after ClientKeyExchange. Related codes:

struct TLSPacket *tls_build_certificate_verify_ex(struct TLSContext *context) {
    if (context->is_server) {
        DEBUG_PRINT("CANNOT BUILD CERTIFICATE VERIFY MESSAGE FOR SERVERS\n");
        return NULL;
    }

    struct TLSPacket *packet = tls_create_packet(context, TLS_HANDSHAKE, context->version, 0);
    tls_packet_uint8(packet, 0x0F);
    unsigned char dummy[3];
    tls_packet_append(packet, dummy, 3);
    if (context->dtls)
        _private_dtls_handshake_data(context, packet, 0);
    int start_len = packet->len;

    if (context->cached_handshake) {
        unsigned char out[TLS_MAX_RSA_KEY];
        unsigned long out_len = TLS_MAX_RSA_KEY;

        int hash_algorithm;
        if ((context->version != TLS_V13) && (context->version != DTLS_V13) && (context->version != TLS_V12) && (context->version != DTLS_V12)) {
            hash_algorithm = _md5_sha1;
        } else {
            if ((context->version == TLS_V13) || (context->version == DTLS_V13) || (context->version == TLS_V12) || (context->version == DTLS_V12))
                hash_algorithm = sha256;
            else
                hash_algorithm = sha1;
#ifdef TLS_ECDSA_SUPPORTED
            if (tls_is_ecdsa(context)) {
                if ((context->version == TLS_V13) || (context->version == DTLS_V13) || (context->version == TLS_V12) || (context->version == DTLS_V12))
                    hash_algorithm = sha512;
                tls_packet_uint8(packet, hash_algorithm);
                tls_packet_uint8(packet, ecdsa);
            } else
#endif
            {
                tls_packet_uint8(packet, hash_algorithm);
                tls_packet_uint8(packet, rsa_sign);
            }
        }

#ifdef TLS_ECDSA_SUPPORTED
        if (tls_is_ecdsa(context)) {
            if (_private_tls_sign_ecdsa(context, hash_algorithm, context->cached_handshake, context->cached_handshake_len, out, &out_len) == 1) {
                DEBUG_PRINT("Signing OK! (ECDSA, length %lu)\n", out_len);
                tls_packet_uint16(packet, out_len);
                tls_packet_append(packet, out, out_len);
            }
        } else
#endif
        if (_private_tls_sign_rsa(context, hash_algorithm, context->cached_handshake, context->cached_handshake_len, out, &out_len) == 1) {
            DEBUG_PRINT("Signing OK! (length %lu)\n", out_len);
            tls_packet_uint16(packet, out_len);
            tls_packet_append(packet, out, out_len);
        }
    }
    if ((!packet->broken) && (packet->buf)) {
        int remaining = packet->len - start_len;
        int payload_pos = 6;
        if (context->dtls)
            payload_pos = 14;
        packet->buf[payload_pos] = remaining / 0x10000;
        remaining %= 0x10000;
        packet->buf[payload_pos + 1] = remaining / 0x100;
        remaining %= 0x100;
        packet->buf[payload_pos + 2] = remaining;
        if (context->dtls) {
            _private_dtls_handshake_copyframesize(packet);
            context->dtls_seq++;
        }
    }
    tls_packet_update(packet);
    return packet;
}
eduardsui commented 5 years ago

Thanks, can you create a PR?