/* this function signs the session id */ STRING *ssh_sign_session_id(SSH_SESSION *session, PRIVATE_KEY *privatekey){ SHACTX ctx; unsigned char hash[SHA_DIGEST_LEN+1]; SIGNATURE *sign; STRING *signature; CRYPTO *crypto=session->current_crypto?session->current_crypto:session->next_crypto; #ifdef HAVE_LIBGCRYPT gcry_sexp_t data_sexp; #endif ctx=sha1_init(); sha1_update(ctx,crypto->session_id,SHA_DIGEST_LEN); sha1_final(hash+1,ctx); hash[0]=0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN); #endif sign=malloc(sizeof(SIGNATURE)); switch(privatekey->type){ case TYPE_DSS: #ifdef HAVE_LIBGCRYPT gcry_sexp_build(&data_sexp,NULL,"%b",SHA_DIGEST_LEN+1,hash); gcry_pk_sign(&sign->dsa_sign,data_sexp,privatekey->dsa_priv); #elif defined HAVE_LIBCRYPTO sign->dsa_sign=DSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->dsa_priv); #ifdef DEBUG_CRYPTO ssh_print_bignum("r",sign->dsa_sign->r); ssh_print_bignum("s",sign->dsa_sign->s); #endif #endif sign->rsa_sign=NULL; break; case TYPE_RSA: #ifdef HAVE_LIBGCRYPT gcry_sexp_build(&data_sexp,NULL,"(data(flags pkcs1)(hash sha1 %b))",SHA_DIGEST_LEN,hash+1); gcry_pk_sign(&sign->rsa_sign,data_sexp,privatekey->rsa_priv); #elif defined HAVE_LIBCRYPTO sign->rsa_sign=RSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->rsa_priv); #endif sign->dsa_sign=NULL; break; } #ifdef HAVE_LIBGCRYPT gcry_sexp_release(data_sexp); #endif sign->type=privatekey->type; if(!sign->dsa_sign && !sign->rsa_sign){ #ifdef HAVE_LIBGCRYPT ssh_set_error(session,SSH_FATAL,"Signing : libgcrypt error"); #elif defined HAVE_LIBCRYPTO ssh_set_error(session,SSH_FATAL,"Signing : openssl error"); #endif signature_free(sign); return NULL; } signature=signature_to_string(sign); signature_free(sign); return signature; }
/* used by server */ int dh_generate_e(ssh_session session) { #ifdef HAVE_LIBCRYPTO bignum_CTX ctx = bignum_ctx_new(); if (ctx == NULL) { return -1; } #endif session->next_crypto->e = bignum_new(); if (session->next_crypto->e == NULL) { #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return -1; } #ifdef HAVE_LIBGCRYPT bignum_mod_exp(session->next_crypto->e, g, session->next_crypto->x, p); #elif defined HAVE_LIBCRYPTO bignum_mod_exp(session->next_crypto->e, g, session->next_crypto->x, p, ctx); #endif #ifdef DEBUG_CRYPTO ssh_print_bignum("e", session->next_crypto->e); #endif #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return 0; }
int dh_generate_f(ssh_session session) { #ifdef HAVE_LIBCRYPTO bignum_CTX ctx = bignum_ctx_new(); if (ctx == NULL) { return -1; } #endif session->next_crypto->f = bignum_new(); if (session->next_crypto->f == NULL) { #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return -1; } #ifdef HAVE_LIBGCRYPT bignum_mod_exp(session->next_crypto->f, g, session->next_crypto->y, select_p(session->next_crypto->kex_type)); #elif defined HAVE_LIBCRYPTO bignum_mod_exp(session->next_crypto->f, g, session->next_crypto->y, select_p(session->next_crypto->kex_type), ctx); #endif #ifdef DEBUG_CRYPTO ssh_print_bignum("f", session->next_crypto->f); #endif #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return 0; }
static int ssh_curve25519_build_k(ssh_session_t * session) { ssh_curve25519_pubkey k; session->next_crypto->k = bignum_new(); if (session->next_crypto->k == NULL) { return SSH_ERROR; } if (session->server) crypto_scalarmult(k, session->next_crypto->curve25519_privkey, session->next_crypto->curve25519_client_pubkey); else crypto_scalarmult(k, session->next_crypto->curve25519_privkey, session->next_crypto->curve25519_server_pubkey); bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k); #ifdef DEBUG_CRYPTO ssh_print_hexa("Session server cookie", session->next_crypto->server_kex.cookie, 16); ssh_print_hexa("Session client cookie", session->next_crypto->client_kex.cookie, 16); ssh_print_bignum("Shared secret key", session->next_crypto->k); #endif return 0; }
struct signature_struct *pki_do_sign(ssh_key privatekey, const unsigned char *hash) { struct signature_struct *sign; sign = malloc(sizeof(SIGNATURE)); if (sign == NULL) { return NULL; } sign->type = privatekey->type; switch(privatekey->type) { case SSH_KEYTYPE_DSS: sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->dsa); if (sign->dsa_sign == NULL) { signature_free(sign); return NULL; } #ifdef DEBUG_CRYPTO ssh_print_bignum("r", sign->dsa_sign->r); ssh_print_bignum("s", sign->dsa_sign->s); #endif sign->rsa_sign = NULL; break; case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->rsa); if (sign->rsa_sign == NULL) { signature_free(sign); return NULL; } sign->dsa_sign = NULL; break; case SSH_KEYTYPE_ECDSA: case SSH_KEYTYPE_UNKNOWN: signature_free(sign); return NULL; } return sign; }
/* used by the server implementation */ int dh_import_e(ssh_session session, ssh_string e_string) { session->next_crypto->e = make_string_bn(e_string); if (session->next_crypto->e == NULL) { return -1; } #ifdef DEBUG_CRYPTO ssh_print_bignum("e",session->next_crypto->e); #endif return 0; }
int dh_import_f(ssh_session session, ssh_string f_string) { session->next_crypto->f = make_string_bn(f_string); if (session->next_crypto->f == NULL) { return -1; } #ifdef DEBUG_CRYPTO ssh_print_bignum("f",session->next_crypto->f); #endif return 0; }
int dh_build_k(ssh_session session) { #ifdef HAVE_LIBCRYPTO bignum_CTX ctx = bignum_ctx_new(); if (ctx == NULL) { return -1; } #endif session->next_crypto->k = bignum_new(); if (session->next_crypto->k == NULL) { #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return -1; } /* the server and clients don't use the same numbers */ #ifdef HAVE_LIBGCRYPT if(session->client) { bignum_mod_exp(session->next_crypto->k, session->next_crypto->f, session->next_crypto->x, select_p(session->next_crypto->kex_type)); } else { bignum_mod_exp(session->next_crypto->k, session->next_crypto->e, session->next_crypto->y, select_p(session->next_crypto->kex_type)); } #elif defined HAVE_LIBCRYPTO if (session->client) { bignum_mod_exp(session->next_crypto->k, session->next_crypto->f, session->next_crypto->x, select_p(session->next_crypto->kex_type), ctx); } else { bignum_mod_exp(session->next_crypto->k, session->next_crypto->e, session->next_crypto->y, select_p(session->next_crypto->kex_type), ctx); } #endif #ifdef DEBUG_CRYPTO ssh_print_hexa("Session server cookie", session->next_crypto->server_kex.cookie, 16); ssh_print_hexa("Session client cookie", session->next_crypto->client_kex.cookie, 16); ssh_print_bignum("Shared secret key", session->next_crypto->k); #endif #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return 0; }
static int ecdh_build_k(ssh_session session) { const EC_GROUP *group = EC_KEY_get0_group(session->next_crypto->ecdh_privkey); EC_POINT *pubkey; void *buffer; int len = (EC_GROUP_get_degree(group) + 7) / 8; bignum_CTX ctx = bignum_ctx_new(); if (ctx == NULL) { return -1; } session->next_crypto->k = bignum_new(); if (session->next_crypto->k == NULL) { bignum_ctx_free(ctx); return -1; } pubkey = EC_POINT_new(group); if (pubkey == NULL) { bignum_ctx_free(ctx); return -1; } if (session->server) EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_client_pubkey), ssh_string_len(session->next_crypto->ecdh_client_pubkey),ctx); else EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_server_pubkey), ssh_string_len(session->next_crypto->ecdh_server_pubkey),ctx); buffer = malloc(len); ECDH_compute_key(buffer,len,pubkey,session->next_crypto->ecdh_privkey,NULL); EC_POINT_free(pubkey); BN_bin2bn(buffer,len,session->next_crypto->k); free(buffer); EC_KEY_free(session->next_crypto->ecdh_privkey); session->next_crypto->ecdh_privkey=NULL; #ifdef DEBUG_CRYPTO ssh_print_hexa("Session server cookie", session->next_crypto->server_kex.cookie, 16); ssh_print_hexa("Session client cookie", session->next_crypto->client_kex.cookie, 16); ssh_print_bignum("Shared secret key", session->next_crypto->k); #endif #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return 0; }
/* used by server */ int dh_generate_y(ssh_session session) { session->next_crypto->y = bignum_new(); if (session->next_crypto->y == NULL) { return -1; } #ifdef HAVE_LIBGCRYPT bignum_rand(session->next_crypto->y, 128); #elif defined HAVE_LIBCRYPTO bignum_rand(session->next_crypto->y, 128, 0, -1); #endif /* not harder than this */ #ifdef DEBUG_CRYPTO ssh_print_bignum("y", session->next_crypto->y); #endif return 0; }
/* this function signs the session id */ ssh_string ssh_sign_session_id(ssh_session session, ssh_private_key privatekey) { struct ssh_crypto_struct *crypto=session->current_crypto ? session->current_crypto : session->next_crypto; unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; ssh_string signature = NULL; SIGNATURE *sign = NULL; SHACTX ctx = NULL; #ifdef HAVE_LIBGCRYPT gcry_sexp_t data_sexp; #endif ctx = sha1_init(); if (ctx == NULL) { return NULL; } sha1_update(ctx,crypto->session_id,SHA_DIGEST_LEN); sha1_final(hash + 1,ctx); hash[0] = 0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN); #endif sign = malloc(sizeof(SIGNATURE)); if (sign == NULL) { return NULL; } ZERO_STRUCTP(sign); switch(privatekey->type) { case SSH_KEYTYPE_DSS: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&data_sexp, NULL, "%b", SHA_DIGEST_LEN + 1, hash) || gcry_pk_sign(&sign->dsa_sign, data_sexp, privatekey->dsa_priv)) { ssh_set_error(session, SSH_FATAL, "Signing: libgcrypt error"); gcry_sexp_release(data_sexp); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->dsa_priv); if (sign->dsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #ifdef DEBUG_CRYPTO ssh_print_bignum("r",sign->dsa_sign->r); ssh_print_bignum("s",sign->dsa_sign->s); #endif #endif /* HAVE_LIBCRYPTO */ sign->rsa_sign = NULL; break; case SSH_KEYTYPE_RSA: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(hash sha1 %b))", SHA_DIGEST_LEN, hash + 1) || gcry_pk_sign(&sign->rsa_sign, data_sexp, privatekey->rsa_priv)) { ssh_set_error(session, SSH_FATAL, "Signing: libgcrypt error"); gcry_sexp_release(data_sexp); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->rsa_priv); if (sign->rsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #endif sign->dsa_sign = NULL; break; default: signature_free(sign); return NULL; } #ifdef HAVE_LIBGCRYPT gcry_sexp_release(data_sexp); #endif sign->type = privatekey->type; signature = signature_to_string(sign); signature_free(sign); return signature; }
/* * This function signs the session id (known as H) as a string then * the content of sigbuf */ STRING *ssh_do_sign(SSH_SESSION *session, BUFFER *sigbuf, PRIVATE_KEY *privatekey) { CRYPTO *crypto = session->current_crypto ? session->current_crypto : session->next_crypto; unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; STRING *session_str = NULL; STRING *signature = NULL; SIGNATURE *sign = NULL; SHACTX ctx = NULL; #ifdef HAVE_LIBGCRYPT gcry_sexp_t gcryhash; #endif session_str = string_new(SHA_DIGEST_LEN); if (session_str == NULL) { return NULL; } string_fill(session_str, crypto->session_id, SHA_DIGEST_LEN); ctx = sha1_init(); if (ctx == NULL) { string_free(session_str); return NULL; } sha1_update(ctx, session_str, string_len(session_str) + 4); string_free(session_str); sha1_update(ctx, buffer_get(sigbuf), buffer_get_len(sigbuf)); sha1_final(hash + 1,ctx); hash[0] = 0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa", hash + 1, SHA_DIGEST_LEN); #endif sign = malloc(sizeof(SIGNATURE)); if (sign == NULL) { return NULL; } switch(privatekey->type) { case TYPE_DSS: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&gcryhash, NULL, "%b", SHA_DIGEST_LEN + 1, hash) || gcry_pk_sign(&sign->dsa_sign, gcryhash, privatekey->dsa_priv)) { ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error"); gcry_sexp_release(gcryhash); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->dsa_priv); if (sign->dsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #ifdef DEBUG_CRYPTO ssh_print_bignum("r", sign->dsa_sign->r); ssh_print_bignum("s", sign->dsa_sign->s); #endif #endif /* HAVE_LIBCRYPTO */ sign->rsa_sign = NULL; break; case TYPE_RSA: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&gcryhash, NULL, "(data(flags pkcs1)(hash sha1 %b))", SHA_DIGEST_LEN, hash + 1) || gcry_pk_sign(&sign->rsa_sign, gcryhash, privatekey->rsa_priv)) { ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error"); gcry_sexp_release(gcryhash); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->rsa_priv); if (sign->rsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #endif sign->dsa_sign = NULL; break; } #ifdef HAVE_LIBGCRYPT gcry_sexp_release(gcryhash); #endif sign->type = privatekey->type; signature = signature_to_string(sign); signature_free(sign); return signature; }