From 33890daf4104238ecf4216102abd0411eed17c43 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 18 Oct 2013 22:45:57 +0200 Subject: [PATCH] pki: Add support for ECDSA private key signing. --- src/pki.c | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/pki.c b/src/pki.c index defc4061..ec5a6883 100644 --- a/src/pki.c +++ b/src/pki.c @@ -1271,11 +1271,9 @@ ssh_string ssh_pki_do_sign(ssh_session session, struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto : session->next_crypto; - unsigned char hash[SHA_DIGEST_LEN] = {0}; ssh_signature sig; ssh_string sig_blob; ssh_string session_id; - SHACTX ctx; int rc; if (privkey == NULL || !ssh_key_is_private(privkey)) { @@ -1287,24 +1285,46 @@ ssh_string ssh_pki_do_sign(ssh_session session, return NULL; } ssh_string_fill(session_id, crypto->session_id, crypto->digest_len); - /* TODO: change when supporting ECDSA keys */ - ctx = sha1_init(); - if (ctx == NULL) { - ssh_string_free(session_id); - return NULL; - } - sha1_update(ctx, session_id, ssh_string_len(session_id) + 4); - ssh_string_free(session_id); + if (privkey->type == SSH_KEYTYPE_ECDSA) { +#ifdef HAVE_ECC + unsigned char ehash[EVP_DIGEST_LEN] = {0}; + uint32_t elen; + EVPCTX ctx; - sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); - sha1_final(hash, ctx); + ctx = evp_init(privkey->ecdsa_nid); + if (ctx == NULL) { + ssh_string_free(session_id); + return NULL; + } + + evp_update(ctx, session_id, ssh_string_len(session_id) + 4); + evp_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); + evp_final(ctx, ehash, &elen); + + sig = pki_do_sign(privkey, ehash, elen); +#endif + } else { + unsigned char hash[SHA_DIGEST_LEN] = {0}; + SHACTX ctx; + + ctx = sha1_init(); + if (ctx == NULL) { + ssh_string_free(session_id); + return NULL; + } + + sha1_update(ctx, session_id, ssh_string_len(session_id) + 4); + sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); + sha1_final(hash, ctx); #ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); + ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); #endif - sig = pki_do_sign(privkey, hash, SHA_DIGEST_LEN); + sig = pki_do_sign(privkey, hash, SHA_DIGEST_LEN); + } + ssh_string_free(session_id); if (sig == NULL) { return NULL; }