int mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) { Buffer m; u_char *blob; u_int len; int verified = 0; debug3("%s entering", __func__); /* Convert the key to a blob and the pass it over */ if (!key_to_blob(key, &blob, &len)) return (0); buffer_init(&m); buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); free(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); verified = buffer_get_int(&m); buffer_free(&m); return (verified); }
int mm_answer_pwnamallow(int sock, Buffer *m) { char *username; struct passwd *pwent; int allowed = 0; debug3("%s", __func__); if (authctxt->attempt++ != 0) fatal("%s: multiple attempts for getpwnam", __func__); username = buffer_get_string(m, NULL); pwent = getpwnamallow(username); authctxt->user = xstrdup(username); setproctitle("%s [priv]", pwent ? username : "******"); xfree(username); buffer_clear(m); if (pwent == NULL) { buffer_put_char(m, 0); authctxt->pw = fakepw(); goto out; } allowed = 1; authctxt->pw = pwent; authctxt->valid = 1; buffer_put_char(m, 1); buffer_put_string(m, pwent, sizeof(struct passwd)); buffer_put_cstring(m, pwent->pw_name); buffer_put_cstring(m, "*"); buffer_put_cstring(m, pwent->pw_gecos); buffer_put_cstring(m, pwent->pw_class); buffer_put_cstring(m, pwent->pw_dir); buffer_put_cstring(m, pwent->pw_shell); out: buffer_put_string(m, &options, sizeof(options)); if (options.banner != NULL) buffer_put_cstring(m, options.banner); debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); mm_request_send(sock, MONITOR_ANS_PWNAM, m); /* For SSHv1 allow authentication now */ if (!compat20) monitor_permit_authentications(1); else { /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); } return (0); }
int mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, const u_char *data, size_t datalen, u_int compat) { Buffer m; u_char *blob; u_int len; u_int encoded_ret = 0; debug3("%s entering", __func__); /* Convert the key to a blob and the pass it over */ if (!key_to_blob(key, &blob, &len)) return (0); buffer_init(&m); buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); free(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); encoded_ret = buffer_get_int(&m); buffer_free(&m); if (encoded_ret != 0) return SSH_ERR_SIGNATURE_INVALID; return 0; }
int mm_sshkey_verify(struct sshkey *key, u_char *sig, u_int siglen, u_char *data, u_int datalen, u_int compat) { Buffer m; u_char *blob; u_int len; int r, verified = 0; debug3("%s entering", __func__); /* Convert the key to a blob and the pass it over */ if ((r = sshkey_to_blob(key, &blob, &len)) != 0) { error("%s: sshkey_to_blob failed: %s", __func__, ssh_err(r)); return (0); } buffer_init(&m); buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); xfree(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); verified = buffer_get_int(&m); buffer_free(&m); return (verified); }
int mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) { Buffer m; u_char *blob; u_int blen; int success = 0; debug3("%s entering", __func__); key->type = KEY_RSA; /* XXX cheat for key_to_blob */ if (key_to_blob(key, &blob, &blen) == 0) fatal("%s: key_to_blob failed", __func__); key->type = KEY_RSA1; buffer_init(&m); buffer_put_string(&m, blob, blen); buffer_put_string(&m, response, 16); free(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m); success = buffer_get_int(&m); buffer_free(&m); return (success); }
// // キー情報からバッファへ変換する (for SSH2) // NOTE: // int key_to_blob(Key *key, char **blobp, int *lenp) { buffer_t *b; char *sshname, *tmp; int len; int ret = 1; // success b = buffer_init(); sshname = get_sshname_from_key(key); switch (key->type) { case KEY_RSA: buffer_put_string(b, sshname, strlen(sshname)); buffer_put_bignum2(b, key->rsa->e); buffer_put_bignum2(b, key->rsa->n); break; case KEY_DSA: buffer_put_string(b, sshname, strlen(sshname)); buffer_put_bignum2(b, key->dsa->p); buffer_put_bignum2(b, key->dsa->q); buffer_put_bignum2(b, key->dsa->g); buffer_put_bignum2(b, key->dsa->pub_key); break; case KEY_ECDSA256: case KEY_ECDSA384: case KEY_ECDSA521: buffer_put_string(b, sshname, strlen(sshname)); tmp = curve_keytype_to_name(key->type); buffer_put_string(b, tmp, strlen(tmp)); buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), EC_KEY_get0_public_key(key->ecdsa)); break; case KEY_ED25519: buffer_put_cstring(b, sshname); buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); break; default: ret = 0; goto error; } len = buffer_len(b); if (lenp != NULL) *lenp = len; if (blobp != NULL) { *blobp = malloc(len); if (*blobp == NULL) { ret = 0; goto error; } memcpy(*blobp, buffer_ptr(b), len); } error: buffer_free(b); return (ret); }
static void ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) { buffer_put_cstring(b, key_ssh_name(key)); switch (key->type) { case KEY_RSA: buffer_put_bignum2(b, key->rsa->n); buffer_put_bignum2(b, key->rsa->e); buffer_put_bignum2(b, key->rsa->d); buffer_put_bignum2(b, key->rsa->iqmp); buffer_put_bignum2(b, key->rsa->p); buffer_put_bignum2(b, key->rsa->q); break; case KEY_RSA_CERT_V00: case KEY_RSA_CERT: if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) fatal("%s: no cert/certblob", __func__); buffer_put_string(b, buffer_ptr(&key->cert->certblob), buffer_len(&key->cert->certblob)); buffer_put_bignum2(b, key->rsa->d); buffer_put_bignum2(b, key->rsa->iqmp); buffer_put_bignum2(b, key->rsa->p); buffer_put_bignum2(b, key->rsa->q); break; case KEY_DSA: buffer_put_bignum2(b, key->dsa->p); buffer_put_bignum2(b, key->dsa->q); buffer_put_bignum2(b, key->dsa->g); buffer_put_bignum2(b, key->dsa->pub_key); buffer_put_bignum2(b, key->dsa->priv_key); break; case KEY_DSA_CERT_V00: case KEY_DSA_CERT: if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) fatal("%s: no cert/certblob", __func__); buffer_put_string(b, buffer_ptr(&key->cert->certblob), buffer_len(&key->cert->certblob)); buffer_put_bignum2(b, key->dsa->priv_key); break; #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid)); buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), EC_KEY_get0_public_key(key->ecdsa)); buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); break; case KEY_ECDSA_CERT: if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) fatal("%s: no cert/certblob", __func__); buffer_put_string(b, buffer_ptr(&key->cert->certblob), buffer_len(&key->cert->certblob)); buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); break; #endif } buffer_put_cstring(b, comment); }
int mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp) { Buffer b; int len; Enc *enc; Mac *mac; Comp *comp; Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode); debug3("%s: converting %p", __func__, newkey); if (newkey == NULL) { error("%s: newkey == NULL", __func__); return 0; } enc = &newkey->enc; mac = &newkey->mac; comp = &newkey->comp; buffer_init(&b); /* Enc structure */ buffer_put_cstring(&b, enc->name); /* The cipher struct is constant and shared, you export pointer */ buffer_append(&b, &enc->cipher, sizeof(enc->cipher)); buffer_put_int(&b, enc->enabled); buffer_put_int(&b, enc->block_size); buffer_put_string(&b, enc->key, enc->key_len); packet_get_keyiv(mode, enc->iv, enc->iv_len); buffer_put_string(&b, enc->iv, enc->iv_len); /* Mac structure */ if (cipher_authlen(enc->cipher) == 0) { buffer_put_cstring(&b, mac->name); buffer_put_int(&b, mac->enabled); buffer_put_string(&b, mac->key, mac->key_len); } /* Comp structure */ buffer_put_int(&b, comp->type); buffer_put_int(&b, comp->enabled); buffer_put_cstring(&b, comp->name); len = buffer_len(&b); if (lenp != NULL) *lenp = len; if (blobp != NULL) { *blobp = xmalloc(len); memcpy(*blobp, buffer_ptr(&b), len); } explicit_bzero(buffer_ptr(&b), len); buffer_free(&b); return len; }
void rexec_send_rng_seed(Buffer *m) { u_char buf[RANDOM_SEED_SIZE]; if (RAND_bytes(buf, sizeof(buf)) <= 0) { error("Couldn't obtain random bytes (error %ld)", ERR_get_error()); buffer_put_string(m, "", 0); } else buffer_put_string(m, buf, sizeof(buf)); }
BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen) { buffer_t *msg = NULL; Key *keypair; char *s, *tmp; msg = buffer_init(); if (msg == NULL) { // TODO: error check return FALSE; } keypair = pvar->auth_state.cur_cred.key_pair; switch (keypair->type) { case KEY_RSA: // RSA s = get_sshname_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_put_bignum2(msg, keypair->rsa->e); // 公開指数 buffer_put_bignum2(msg, keypair->rsa->n); // p×q break; case KEY_DSA: // DSA s = get_sshname_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_put_bignum2(msg, keypair->dsa->p); // 素数 buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)の素因数 buffer_put_bignum2(msg, keypair->dsa->g); // 整数 buffer_put_bignum2(msg, keypair->dsa->pub_key); // 公開鍵 break; case KEY_ECDSA256: // ECDSA case KEY_ECDSA384: case KEY_ECDSA521: s = get_sshname_from_key(keypair); buffer_put_string(msg, s, strlen(s)); tmp = curve_keytype_to_name(keypair->type); buffer_put_string(msg, tmp, strlen(tmp)); buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa), EC_KEY_get0_public_key(keypair->ecdsa)); break; case KEY_ED25519: s = get_sshname_from_key(keypair); buffer_put_cstring(msg, s); buffer_put_string(msg, keypair->ed25519_pk, ED25519_PK_SZ); break; default: return FALSE; } *blobptr = msg; *bloblen = buffer_len(msg); return TRUE; }
static void mm_send_kex(Buffer *m, Kex *kex) { buffer_put_string(m, kex->session_id, kex->session_id_len); buffer_put_int(m, kex->we_need); buffer_put_int(m, kex->hostkey_type); buffer_put_int(m, kex->kex_type); buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my)); buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer)); buffer_put_int(m, kex->flags); buffer_put_cstring(m, kex->client_version_string); buffer_put_cstring(m, kex->server_version_string); }
unsigned char *kex_ecdh_hash(const EVP_MD *evp_md, const EC_GROUP *ec_group, char *client_version_string, char *server_version_string, char *ckexinit, int ckexinitlen, char *skexinit, int skexinitlen, u_char *serverhostkeyblob, int sbloblen, const EC_POINT *client_dh_pub, const EC_POINT *server_dh_pub, BIGNUM *shared_secret, unsigned int *hashlen) { buffer_t *b; static unsigned char digest[EVP_MAX_MD_SIZE]; EVP_MD_CTX md; b = buffer_init(); buffer_put_string(b, client_version_string, strlen(client_version_string)); buffer_put_string(b, server_version_string, strlen(server_version_string)); /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ buffer_put_int(b, ckexinitlen+1); buffer_put_char(b, SSH2_MSG_KEXINIT); buffer_append(b, ckexinit, ckexinitlen); buffer_put_int(b, skexinitlen+1); buffer_put_char(b, SSH2_MSG_KEXINIT); buffer_append(b, skexinit, skexinitlen); buffer_put_string(b, serverhostkeyblob, sbloblen); buffer_put_ecpoint(b, ec_group, client_dh_pub); buffer_put_ecpoint(b, ec_group, server_dh_pub); buffer_put_bignum2(b, shared_secret); // yutaka //debug_print(38, buffer_ptr(b), buffer_len(b)); EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b)); EVP_DigestFinal(&md, digest, NULL); buffer_free(b); //write_buffer_file(digest, EVP_MD_size(evp_md)); *hashlen = EVP_MD_size(evp_md); return digest; }
void buffer_put_cstring(Buffer *buffer, const char *s) { if (s == NULL) fatal("buffer_put_cstring: s == NULL"); buffer_put_string(buffer, s, strlen(s)); }
int packet_fxp_fsetstat(Buffer *buff, Buffer *preped_buff) { u_int msg_len; u_int xmsg_len; // File names u_int file_len; u_char *handle; // Copy first part of packet over to prepared buffer msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; buffer_append(preped_buff, buffer_ptr(buff), 9); buffer_consume(buff, 9); xmsg_len -= 5; // Copy handle handle = buffer_get_string(buff, &file_len); buffer_put_string(preped_buff, (char*) handle, file_len); xmsg_len -= (file_len + 4); // Copy attributes through, cleaning extensions where required parse_attrs(buff, preped_buff, &msg_len, &xmsg_len); // Copy any remaining packet data over buffer_append(preped_buff, buffer_ptr(buff), xmsg_len); buffer_consume(buff, xmsg_len); // Rewrite message length put_u32(buffer_end(preped_buff)-msg_len-4, msg_len); return 1; }
int mm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply) { KTEXT auth, reply; Buffer m; u_int rlen; int success = 0; char *p; debug3("%s entering", __func__); auth = _auth; reply = _reply; buffer_init(&m); buffer_put_string(&m, auth->dat, auth->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB4, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB4, &m); success = buffer_get_int(&m); if (success) { *client = buffer_get_string(&m, NULL); p = buffer_get_string(&m, &rlen); if (rlen >= MAX_KTXT_LEN) fatal("%s: reply from monitor too large", __func__); reply->length = rlen; memcpy(reply->dat, p, rlen); memset(p, 0, rlen); xfree(p); } buffer_free(&m); return (success); }
int mm_answer_krb5(int socket, Buffer *m) { krb5_data tkt, reply; char *client_user; u_int len; int success; /* use temporary var to avoid size issues on 64bit arch */ tkt.data = buffer_get_string(m, &len); tkt.length = len; success = options.kerberos_authentication && authctxt->valid && auth_krb5(authctxt, &tkt, &client_user, &reply); if (tkt.length) xfree(tkt.data); buffer_clear(m); buffer_put_int(m, success); if (success) { buffer_put_cstring(m, client_user); buffer_put_string(m, reply.data, reply.length); if (client_user) xfree(client_user); if (reply.length) xfree(reply.data); } mm_request_send(socket, MONITOR_ANS_KRB5, m); return success; }
int mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp) { krb5_data *tkt, *reply; Buffer m; int success; debug3("%s entering", __func__); tkt = (krb5_data *) argp; reply = (krb5_data *) resp; buffer_init(&m); buffer_put_string(&m, tkt->data, tkt->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB5, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB5, &m); success = buffer_get_int(&m); if (success) { u_int len; *userp = buffer_get_string(&m, NULL); reply->data = buffer_get_string(&m, &len); reply->length = len; } else { memset(reply, 0, sizeof(*reply)); *userp = NULL; } buffer_free(&m); return (success); }
int ssh_remove_identity(AuthenticationConnection *auth, Key *key) { Buffer msg; int type; u_char *blob; u_int blen; buffer_init(&msg); if (key->type == KEY_RSA1) { buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY); buffer_put_int(&msg, BN_num_bits(key->rsa->n)); buffer_put_bignum(&msg, key->rsa->e); buffer_put_bignum(&msg, key->rsa->n); } else if (key->type == KEY_DSA || key->type == KEY_RSA) { key_to_blob(key, &blob, &blen); buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); buffer_put_string(&msg, blob, blen); xfree(blob); } else { buffer_free(&msg); return 0; } if (ssh_request_reply(auth, &msg, &msg) == 0) { buffer_free(&msg); return 0; } type = buffer_get_char(&msg); buffer_free(&msg); return decode_reply(type); }
int mm_answer_gss_accept_ctx(int sock, Buffer *m) { gss_buffer_desc in; gss_buffer_desc out = GSS_C_EMPTY_BUFFER; OM_uint32 major, minor; OM_uint32 flags = 0; /* GSI needs this */ u_int len; in.value = buffer_get_string(m, &len); in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); xfree(in.value); buffer_clear(m); buffer_put_int(m, major); buffer_put_string(m, out.value, out.length); buffer_put_int(m, flags); mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); gss_release_buffer(&minor, &out); if (major == GSS_S_COMPLETE) { monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); } return (0); }
/* * Stores a string using the bignum encoding rules (\0 pad if MSB set). */ void buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l) { u_char *buf, *p; int pad = 0; if (l > 8 * 1024) fatal("%s: length %u too long", __func__, l); /* Skip leading zero bytes */ for (; l > 0 && *s == 0; l--, s++) ; p = buf = xmalloc(l + 1); /* * If most significant bit is set then prepend a zero byte to * avoid interpretation as a negative number. */ if (l > 0 && (s[0] & 0x80) != 0) { *p++ = '\0'; pad = 1; } memcpy(p, s, l); buffer_put_string(buffer, buf, l + pad); explicit_bzero(buf, l + pad); free(buf); }
int mm_jpake_check_confirm(const BIGNUM *k, const u_char *peer_id, u_int peer_id_len, const u_char *sess_id, u_int sess_id_len, const u_char *peer_confirm_hash, u_int peer_confirm_hash_len) { Buffer m; int success = 0; debug3("%s entering", __func__); buffer_init(&m); /* k is dummy in slave, ignored */ /* monitor knows all the ids */ buffer_put_string(&m, peer_confirm_hash, peer_confirm_hash_len); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_JPAKE_CHECK_CONFIRM, &m); debug3("%s: waiting for MONITOR_ANS_JPAKE_CHECK_CONFIRM", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_JPAKE_CHECK_CONFIRM, &m); success = buffer_get_int(&m); buffer_free(&m); debug3("%s: success = %d", __func__, success); return success; }
BIGNUM * mm_auth_rsa_generate_challenge(Key *key) { Buffer m; BIGNUM *challenge; u_char *blob; u_int blen; debug3("%s entering", __func__); if ((challenge = BN_new()) == NULL) fatal("%s: BN_new failed", __func__); key->type = KEY_RSA; /* XXX cheat for key_to_blob */ if (key_to_blob(key, &blob, &blen) == 0) fatal("%s: key_to_blob failed", __func__); key->type = KEY_RSA1; buffer_init(&m); buffer_put_string(&m, blob, blen); xfree(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m); buffer_get_bignum2(&m, challenge); buffer_free(&m); return (challenge); }
void mm_jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val, BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2, BIGNUM *theirpub1, BIGNUM *theirpub2, const u_char *my_id, u_int my_id_len, const u_char *their_id, u_int their_id_len, const u_char *sess_id, u_int sess_id_len, const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len, BIGNUM **k, u_char **confirm_hash, u_int *confirm_hash_len) { Buffer m; debug3("%s entering", __func__); buffer_init(&m); /* monitor already has all bignums except step2_val */ buffer_put_bignum2(&m, step2_val); /* monitor already knows all the ids */ buffer_put_string(&m, theirpriv2_s_proof, theirpriv2_s_proof_len); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_JPAKE_KEY_CONFIRM, &m); debug3("%s: waiting for MONITOR_ANS_JPAKE_KEY_CONFIRM", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_JPAKE_KEY_CONFIRM, &m); /* 'k' is sensitive and stays in the monitor */ *confirm_hash = buffer_get_string(&m, confirm_hash_len); buffer_free(&m); }
static int ssh_ed25519_sign(Key *key, char **sigp, int *lenp, char *data, int datalen) { char *sig; int slen, len; unsigned long long smlen; int ret; buffer_t *b; smlen = slen = datalen + crypto_sign_ed25519_BYTES; sig = malloc(slen); if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen, key->ed25519_sk)) != 0 || smlen <= datalen) { //error("%s: crypto_sign_ed25519 failed: %d", __func__, ret); free(sig); return -1; } /* encode signature */ b = buffer_init(); buffer_put_cstring(b, "ssh-ed25519"); buffer_put_string(b, sig, (int)(smlen - datalen)); len = buffer_len(b); if (lenp != NULL) *lenp = len; if (sigp != NULL) { *sigp = malloc(len); memcpy(*sigp, buffer_ptr(b), len); } buffer_free(b); memset(sig, 's', slen); free(sig); return 0; }
void kex_c25519_hash( int hash_alg, char *client_version_string, char *server_version_string, char *ckexinit, int ckexinitlen, char *skexinit, int skexinitlen, u_char *serverhostkeyblob, int sbloblen, const u_char client_dh_pub[CURVE25519_SIZE], const u_char server_dh_pub[CURVE25519_SIZE], const u_char *shared_secret, u_int secretlen, u_char **hash, u_int *hashlen) { Buffer b; static u_char digest[SSH_DIGEST_MAX_LENGTH]; buffer_init(&b); buffer_put_cstring(&b, client_version_string); buffer_put_cstring(&b, server_version_string); /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ buffer_put_int(&b, ckexinitlen+1); buffer_put_char(&b, SSH2_MSG_KEXINIT); buffer_append(&b, ckexinit, ckexinitlen); buffer_put_int(&b, skexinitlen+1); buffer_put_char(&b, SSH2_MSG_KEXINIT); buffer_append(&b, skexinit, skexinitlen); buffer_put_string(&b, serverhostkeyblob, sbloblen); buffer_put_string(&b, client_dh_pub, CURVE25519_SIZE); buffer_put_string(&b, server_dh_pub, CURVE25519_SIZE); buffer_append(&b, shared_secret, secretlen); #ifdef DEBUG_KEX buffer_dump(&b); #endif if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) fatal("%s: digest_buffer failed", __func__); buffer_free(&b); #ifdef DEBUG_KEX dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); #endif *hash = digest; *hashlen = ssh_digest_bytes(hash_alg); }
void kexgex_hash( const EVP_MD *evp_md, char *client_version_string, char *server_version_string, char *ckexinit, int ckexinitlen, char *skexinit, int skexinitlen, u_char *serverhostkeyblob, int sbloblen, int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen, BIGNUM *client_dh_pub, BIGNUM *server_dh_pub, BIGNUM *shared_secret, u_char **hash, u_int *hashlen) { Buffer b; static u_char digest[EVP_MAX_MD_SIZE]; EVP_MD_CTX md; buffer_init(&b); buffer_put_cstring(&b, client_version_string); buffer_put_cstring(&b, server_version_string); /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ buffer_put_int(&b, ckexinitlen+1); buffer_put_char(&b, SSH2_MSG_KEXINIT); buffer_append(&b, ckexinit, ckexinitlen); buffer_put_int(&b, skexinitlen+1); buffer_put_char(&b, SSH2_MSG_KEXINIT); buffer_append(&b, skexinit, skexinitlen); buffer_put_string(&b, serverhostkeyblob, sbloblen); if (min == -1 || max == -1) buffer_put_int(&b, wantbits); else { buffer_put_int(&b, min); buffer_put_int(&b, wantbits); buffer_put_int(&b, max); } buffer_put_bignum2(&b, prime); buffer_put_bignum2(&b, gen); buffer_put_bignum2(&b, client_dh_pub); buffer_put_bignum2(&b, server_dh_pub); buffer_put_bignum2(&b, shared_secret); #ifdef DEBUG_KEXDH buffer_dump(&b); #endif EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); EVP_DigestFinal(&md, digest, NULL); buffer_free(&b); *hash = digest; *hashlen = EVP_MD_size(evp_md); #ifdef DEBUG_KEXDH dump_digest("hash", digest, *hashlen); #endif }
void kexgex_hash( int hash_alg, char *client_version_string, char *server_version_string, char *ckexinit, int ckexinitlen, char *skexinit, int skexinitlen, u_char *serverhostkeyblob, int sbloblen, int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen, BIGNUM *client_dh_pub, BIGNUM *server_dh_pub, BIGNUM *shared_secret, u_char **hash, u_int *hashlen) { Buffer b; static u_char digest[SSH_DIGEST_MAX_LENGTH]; buffer_init(&b); buffer_put_cstring(&b, client_version_string); buffer_put_cstring(&b, server_version_string); /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ buffer_put_int(&b, ckexinitlen+1); buffer_put_char(&b, SSH2_MSG_KEXINIT); buffer_append(&b, ckexinit, ckexinitlen); buffer_put_int(&b, skexinitlen+1); buffer_put_char(&b, SSH2_MSG_KEXINIT); buffer_append(&b, skexinit, skexinitlen); buffer_put_string(&b, serverhostkeyblob, sbloblen); if (min == -1 || max == -1) buffer_put_int(&b, wantbits); else { buffer_put_int(&b, min); buffer_put_int(&b, wantbits); buffer_put_int(&b, max); } buffer_put_bignum2(&b, prime); buffer_put_bignum2(&b, gen); buffer_put_bignum2(&b, client_dh_pub); buffer_put_bignum2(&b, server_dh_pub); buffer_put_bignum2(&b, shared_secret); #ifdef DEBUG_KEXDH buffer_dump(&b); #endif if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) fatal("%s: ssh_digest_buffer failed", __func__); buffer_free(&b); #ifdef DEBUG_KEX dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); #endif *hash = digest; *hashlen = ssh_digest_bytes(hash_alg); }
OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) { Buffer m; OM_uint32 major; buffer_init(&m); buffer_put_string(&m, gssbuf->value, gssbuf->length); buffer_put_string(&m, gssmic->value, gssmic->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, &m); major = buffer_get_int(&m); buffer_free(&m); return(major); }
int mm_answer_jpake_step1(int sock, Buffer *m) { struct jpake_ctx *pctx; u_char *x3_proof, *x4_proof; u_int x3_proof_len, x4_proof_len; if (!options.zero_knowledge_password_authentication) fatal("zero_knowledge_password_authentication disabled"); if (authctxt->jpake_ctx != NULL) fatal("%s: authctxt->jpake_ctx already set (%p)", __func__, authctxt->jpake_ctx); authctxt->jpake_ctx = pctx = jpake_new(); jpake_step1(pctx->grp, &pctx->server_id, &pctx->server_id_len, &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, &x3_proof, &x3_proof_len, &x4_proof, &x4_proof_len); JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__)); buffer_clear(m); buffer_put_string(m, pctx->server_id, pctx->server_id_len); buffer_put_bignum2(m, pctx->g_x3); buffer_put_bignum2(m, pctx->g_x4); buffer_put_string(m, x3_proof, x3_proof_len); buffer_put_string(m, x4_proof, x4_proof_len); debug3("%s: sending step1", __func__); mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m); bzero(x3_proof, x3_proof_len); bzero(x4_proof, x4_proof_len); xfree(x3_proof); xfree(x4_proof); monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1); monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0); return 0; }
void SFTP::run () { void* inputMsg = 0; u_int32_t inputMsgLen; try { for (;;) { // wait until an input message arrived inputMsg = fromChannel->get (&inputMsgLen, 0, 0); if (inputMsgLen == 0) { ssh::xfree (inputMsg); inputMsg = 0; assert (fromChannel->n_msgs_in_the_buffer () == 0); if (fromChannel->n_msgs_in_the_buffer () != 0) { LOG4CXX_ERROR (Logging::Root (), L"Program error: EOF received but the input buffer" L" contains more data to process. The SFTP session" L" will not be closed (resource leak)."); continue; } // the buffer should be empty return; // exit the thread } else { // copy to SFTP::iqueue buffer_put_string(&iqueue, inputMsg, inputMsgLen); ssh::xfree (inputMsg); inputMsg = 0; } /* * Process requests from client if we can fit the results * into the output buffer, otherwise stop processing input * and let the output queue drain. */ // FIXME check fitting in output buffer process(); // FIXME no backpressure at all (see OpenSSH) } } catch (...) { if (inputMsg) ssh::xfree (inputMsg); throw; } }