Beispiel #1
0
/*
 * Ensure the client has the private key by first decrypting the packet and
 * then checking the packet digests.
 */
static int process_cert_verify(SSL *ssl)
{
    uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
    int pkt_size = ssl->bm_index;
    uint8_t dgst_buf[MAX_KEY_BYTE_SIZE];
    uint8_t dgst[MD5_SIZE+SHA1_SIZE];
    X509_CTX *x509_ctx = ssl->x509_ctx;
    int ret = SSL_OK;
    int n;

    PARANOIA_CHECK(pkt_size, x509_ctx->rsa_ctx->num_octets+6);
    DISPLAY_RSA(ssl, x509_ctx->rsa_ctx);

    /* rsa_ctx->bi_ctx is not thread-safe */
    SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
    n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[6], dgst_buf, 0);
    SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);

    if (n != SHA1_SIZE + MD5_SIZE)
    {
        ret = SSL_ERROR_INVALID_KEY;
        goto end_cert_vfy;
    }

    finished_digest(ssl, NULL, dgst);       /* calculate the digest */
    if (memcmp(dgst_buf, dgst, MD5_SIZE + SHA1_SIZE))
    {
        ret = SSL_ERROR_INVALID_KEY;
    }

end_cert_vfy:
    ssl->next_state = HS_FINISHED;
error:
    return ret;
}
Beispiel #2
0
/*
 * Send a certificate verify message.
 */
static int send_cert_verify(SSL *ssl)
{
    uint8_t *buf = ssl->bm_data;
    uint8_t dgst[MD5_SIZE+SHA1_SIZE];
    RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx;
    int n = 0, ret;

    if (rsa_ctx == NULL)
        return SSL_OK;

    DISPLAY_RSA(ssl, rsa_ctx);

    buf[0] = HS_CERT_VERIFY;
    buf[1] = 0;

    finished_digest(ssl, NULL, dgst);   /* calculate the digest */

    /* rsa_ctx->bi_ctx is not thread-safe */
    if (rsa_ctx)
    {
        SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
        n = RSA_encrypt(rsa_ctx, dgst, sizeof(dgst), &buf[6], 1);
        SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);

        if (n == 0)
        {
            ret = SSL_ERROR_INVALID_KEY;
            goto error;
        }
    }
    
    buf[4] = n >> 8;        /* add the RSA size (not officially documented) */
    buf[5] = n & 0xff;
    n += 2;
    buf[2] = n >> 8;
    buf[3] = n & 0xff;
    ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n+4);

error:
    return ret;
}
/*
 * Ensure the client has the private key by first decrypting the packet and
 * then checking the packet digests.
 */
static int process_cert_verify(SSL *ssl)
{
    uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
    int pkt_size = ssl->bm_index;
    uint8_t dgst_buf[MAX_KEY_BYTE_SIZE];
    uint8_t dgst[MD5_SIZE + SHA1_SIZE];
    X509_CTX *x509_ctx = ssl->x509_ctx;
    int ret = SSL_OK;
    int offset = 6;
    int rsa_len;
    int n;

    DISPLAY_RSA(ssl, x509_ctx->rsa_ctx);

    if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+
    {
        // TODO: should really need to be able to handle other algorihms. An 
        // assumption is made on RSA/SHA256 and appears to be OK.
        //uint8_t hash_alg = buf[4];
        //uint8_t sig_alg = buf[5];
        offset = 8;
        rsa_len = (buf[6] << 8) + buf[7];
    }
    else
    {
        rsa_len = (buf[4] << 8) + buf[5];
    }

    PARANOIA_CHECK(pkt_size, offset + rsa_len);

    /* rsa_ctx->bi_ctx is not thread-safe */
    SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
    n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[offset], dgst_buf, 
                    sizeof(dgst_buf), 0);
    SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);

    if (ssl->version >= SSL_PROTOCOL_VERSION_TLS1_2) // TLS1.2+
    {
        if (memcmp(dgst_buf, g_asn1_sha256, sizeof(g_asn1_sha256)))
        {
            ret = SSL_ERROR_INVALID_KEY;
            goto error;
        }

        finished_digest(ssl, NULL, dgst);       /* calculate the digest */
        if (memcmp(&dgst_buf[sizeof(g_asn1_sha256)], dgst, SHA256_SIZE))
        {
            ret = SSL_ERROR_INVALID_KEY;
            goto error;
        }
    }
    else // TLS1.0/1.1
    {
        if (n != SHA1_SIZE + MD5_SIZE)
        {
            ret = SSL_ERROR_INVALID_KEY;
            goto end_cert_vfy;
        }

        finished_digest(ssl, NULL, dgst);       /* calculate the digest */
        if (memcmp(dgst_buf, dgst, MD5_SIZE + SHA1_SIZE))
        {
            ret = SSL_ERROR_INVALID_KEY;
        }
    }

end_cert_vfy:
    ssl->next_state = HS_FINISHED;
error:
    return ret;
}