int ssh_pki_signature_verify_blob(ssh_session session, ssh_string sig_blob, const ssh_key key, unsigned char *digest, size_t dlen) { ssh_signature sig; int rc; rc = ssh_pki_import_signature_blob(sig_blob, key, &sig); if (rc < 0) { return SSH_ERROR; } SSH_LOG(SSH_LOG_FUNCTIONS, "Going to verify a %s type signature", key->type_c); if (key->type == SSH_KEYTYPE_ECDSA) { #if HAVE_ECC unsigned char ehash[EVP_DIGEST_LEN] = {0}; uint32_t elen; evp(key->ecdsa_nid, digest, dlen, ehash, &elen); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash to be verified with ecdsa", ehash, elen); #endif rc = pki_signature_verify(session, sig, key, ehash, elen); #endif } else if (key->type == SSH_KEYTYPE_ED25519) { rc = pki_signature_verify(session, sig, key, digest, dlen); } else { unsigned char hash[SHA_DIGEST_LEN] = {0}; sha1(digest, dlen, hash); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash to be verified with dsa", hash, SHA_DIGEST_LEN); #endif rc = pki_signature_verify(session, sig, key, hash, SHA_DIGEST_LEN); } ssh_signature_free(sig); return rc; }
static void torture_pki_generate_key_ecdsa(void **state) { int rc; ssh_key key; ssh_signature sign; ssh_session session=ssh_new(); (void) state; rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 256, &key); assert_true(rc == SSH_OK); assert_true(key != NULL); sign = pki_do_sign(key, HASH, 20); assert_true(sign != NULL); rc = pki_signature_verify(session,sign,key,HASH,20); assert_true(rc == SSH_OK); ssh_signature_free(sign); ssh_key_free(key); key=NULL; rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 384, &key); assert_true(rc == SSH_OK); assert_true(key != NULL); sign = pki_do_sign(key, HASH, 20); assert_true(sign != NULL); rc = pki_signature_verify(session,sign,key,HASH,20); assert_true(rc == SSH_OK); ssh_signature_free(sign); ssh_key_free(key); key=NULL; rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 512, &key); assert_true(rc == SSH_OK); assert_true(key != NULL); sign = pki_do_sign(key, HASH, 20); assert_true(sign != NULL); rc = pki_signature_verify(session,sign,key,HASH,20); assert_true(rc == SSH_OK); ssh_signature_free(sign); ssh_key_free(key); key=NULL; ssh_free(session); }
static void torture_pki_generate_key_rsa1(void **state) { int rc; ssh_key key; ssh_signature sign; ssh_session session=ssh_new(); (void) state; rc = ssh_pki_generate(SSH_KEYTYPE_RSA1, 1024, &key); assert_true(rc == SSH_OK); assert_true(key != NULL); sign = pki_do_sign(key, HASH, 20); assert_true(sign != NULL); rc = pki_signature_verify(session,sign,key,HASH,20); assert_true(rc == SSH_OK); ssh_signature_free(sign); ssh_key_free(key); key=NULL; rc = ssh_pki_generate(SSH_KEYTYPE_RSA1, 2048, &key); assert_true(rc == SSH_OK); assert_true(key != NULL); sign = pki_do_sign(key, HASH, 20); assert_true(sign != NULL); rc = pki_signature_verify(session,sign,key,HASH,20); assert_true(rc == SSH_OK); ssh_signature_free(sign); ssh_key_free(key); key=NULL; rc = ssh_pki_generate(SSH_KEYTYPE_RSA1, 4096, &key); assert_true(rc == SSH_OK); assert_true(key != NULL); sign = pki_do_sign(key, HASH, 20); assert_true(sign != NULL); rc = pki_signature_verify(session,sign,key,HASH,20); assert_true(rc == SSH_OK); ssh_signature_free(sign); ssh_key_free(key); key=NULL; ssh_free(session); }
static void torture_pki_signature(void **state) { ssh_signature sig; (void) state; /* unused */ sig = ssh_signature_new(); assert_true(sig != NULL); ssh_signature_free(sig); }
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, const ssh_key privkey) { struct ssh_crypto_struct *crypto; ssh_signature sig = NULL; ssh_string sig_blob; int rc; if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) { return NULL; } crypto = session->next_crypto ? session->next_crypto : session->current_crypto; if (crypto->secret_hash == NULL){ ssh_set_error(session,SSH_FATAL,"Missing secret_hash"); return NULL; } if (privkey->type == SSH_KEYTYPE_ECDSA) { #ifdef HAVE_ECC unsigned char ehash[EVP_DIGEST_LEN] = {0}; uint32_t elen; evp(privkey->ecdsa_nid, crypto->secret_hash, crypto->digest_len, ehash, &elen); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed", ehash, elen); #endif sig = pki_do_sign_sessionid(privkey, ehash, elen); if (sig == NULL) { return NULL; } #endif } else if (privkey->type == SSH_KEYTYPE_ED25519) { sig = ssh_signature_new(); if (sig == NULL){ return NULL; } sig->type = privkey->type; sig->type_c = privkey->type_c; rc = pki_ed25519_sign(privkey, sig, crypto->secret_hash, crypto->digest_len); if (rc != SSH_OK){ ssh_signature_free(sig); sig = NULL; } } else { unsigned char hash[SHA_DIGEST_LEN] = {0}; SHACTX ctx; ctx = sha1_init(); if (ctx == NULL) { return NULL; } sha1_update(ctx, crypto->secret_hash, crypto->digest_len); sha1_final(hash, ctx); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); #endif sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN); if (sig == NULL) { return NULL; } } rc = ssh_pki_export_signature_blob(sig, &sig_blob); ssh_signature_free(sig); if (rc < 0) { return NULL; } return sig_blob; }
/* * This function signs the session id as a string then * the content of sigbuf */ ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf, const ssh_key privkey) { struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto : session->next_crypto; ssh_signature sig = NULL; ssh_string sig_blob; ssh_string session_id; int rc; if (privkey == NULL || !ssh_key_is_private(privkey)) { return NULL; } session_id = ssh_string_new(crypto->digest_len); if (session_id == NULL) { return NULL; } ssh_string_fill(session_id, crypto->session_id, crypto->digest_len); if (privkey->type == SSH_KEYTYPE_ECDSA) { #ifdef HAVE_ECC unsigned char ehash[EVP_DIGEST_LEN] = {0}; uint32_t elen; EVPCTX 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, ssh_buffer_get(sigbuf), ssh_buffer_get_len(sigbuf)); evp_final(ctx, ehash, &elen); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed", ehash, elen); #endif sig = pki_do_sign(privkey, ehash, elen); #endif } else if (privkey->type == SSH_KEYTYPE_ED25519){ ssh_buffer buf; buf = ssh_buffer_new(); if (buf == NULL) { ssh_string_free(session_id); return NULL; } ssh_buffer_set_secure(buf); rc = ssh_buffer_pack(buf, "SP", session_id, ssh_buffer_get_len(sigbuf), ssh_buffer_get(sigbuf)); if (rc != SSH_OK) { ssh_string_free(session_id); ssh_buffer_free(buf); return NULL; } sig = pki_do_sign(privkey, ssh_buffer_get(buf), ssh_buffer_get_len(buf)); ssh_buffer_free(buf); } 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, ssh_buffer_get(sigbuf), ssh_buffer_get_len(sigbuf)); sha1_final(hash, ctx); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); #endif sig = pki_do_sign(privkey, hash, SHA_DIGEST_LEN); } ssh_string_free(session_id); if (sig == NULL) { return NULL; } rc = ssh_pki_export_signature_blob(sig, &sig_blob); ssh_signature_free(sig); if (rc < 0) { return NULL; } return sig_blob; }