/* Confirmation hash calculation */ void jpake_confirm_hash(const BIGNUM *k, const u_char *endpoint_id, u_int endpoint_id_len, const u_char *sess_id, u_int sess_id_len, u_char **confirm_hash, u_int *confirm_hash_len) { Buffer b; /* * Calculate confirmation proof: * client: H(k || client_id || session_id) * server: H(k || server_id || session_id) */ buffer_init(&b); buffer_put_bignum2(&b, k); buffer_put_string(&b, endpoint_id, endpoint_id_len); buffer_put_string(&b, sess_id, sess_id_len); if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(), confirm_hash, confirm_hash_len) != 0) fatal("%s: hash_buffer", __func__); buffer_free(&b); }
int mm_answer_rsa_challenge(int sock, Buffer *m) { Key *key = NULL; u_char *blob; u_int blen; debug3("%s entering", __func__); if (!authctxt->valid) fatal("%s: authctxt not valid", __func__); blob = buffer_get_string(m, &blen); if (!monitor_allowed_key(blob, blen)) fatal("%s: bad key, not previously allowed", __func__); if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) fatal("%s: key type mismatch", __func__); if ((key = key_from_blob(blob, blen)) == NULL) fatal("%s: received bad key", __func__); if (key->type != KEY_RSA) fatal("%s: received bad key type %d", __func__, key->type); key->type = KEY_RSA1; if (ssh1_challenge) BN_clear_free(ssh1_challenge); ssh1_challenge = auth_rsa_generate_challenge(key); buffer_clear(m); buffer_put_bignum2(m, ssh1_challenge); debug3("%s sending reply", __func__); mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); xfree(blob); key_free(key); return (0); }
int mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, struct sshkey **rkey) { Buffer m; struct sshkey *key; u_char *blob; u_int blen; int r, allowed = 0, have_forced = 0; debug3("%s entering", __func__); buffer_init(&m); buffer_put_bignum2(&m, client_n); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); allowed = buffer_get_int(&m); /* fake forced command */ auth_clear_options(); have_forced = buffer_get_int(&m); forced_command = have_forced ? xstrdup("true") : NULL; if (allowed && rkey != NULL) { blob = buffer_get_string(&m, &blen); if ((r = sshkey_from_blob(blob, blen, &key)) != 0) fatal("%s: key_from_blob failed: %s", __func__, ssh_err(r)); *rkey = key; xfree(blob); } buffer_free(&m); return (allowed); }
void key_private_serialize(Key *key, buffer_t *b) { char *s; s = get_sshname_from_key(key); buffer_put_cstring(b, s); 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_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_ECDSA256: case KEY_ECDSA384: case KEY_ECDSA521: buffer_put_cstring(b, curve_keytype_to_name(key->type)); buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), EC_KEY_get0_public_key(key->ecdsa)); buffer_put_bignum2(b, (BIGNUM *)EC_KEY_get0_private_key(key->ecdsa)); break; case KEY_ED25519: buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ); break; default: break; } }
BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen) { buffer_t *msg = NULL; char *s; int ret; msg = buffer_init(); if (msg == NULL) { // TODO: error check return FALSE; } switch (keypair->type) { case KEY_RSA: // RSA { const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE], *sig; u_int slen, dlen, len; int ok, nid = NID_sha1; // ダイジェスト値の計算 EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); slen = RSA_size(keypair->rsa); sig = malloc(slen); if (sig == NULL) goto error; // 電子署名を計算 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa); memset(digest, 'd', sizeof(digest)); if (ok != 1) { // error free(sig); goto error; } // 署名のサイズがバッファより小さい場合、後ろへずらす。先頭はゼロで埋める。 if (len < slen) { u_int diff = slen - len; memmove(sig + diff, sig, len); memset(sig, 0, diff); } else if (len > slen) { free(sig); goto error; } else { // do nothing } s = get_sshname_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_append_length(msg, sig, slen); len = buffer_len(msg); // setting *siglen = len; *sigptr = malloc(len); if (*sigptr == NULL) { free(sig); goto error; } memcpy(*sigptr, buffer_ptr(msg), len); free(sig); break; } case KEY_DSA: // DSA { DSA_SIG *sig; const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN]; u_int rlen, slen, len, dlen; // ダイジェストの計算 EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); // DSA電子署名を計算 sig = DSA_do_sign(digest, dlen, keypair->dsa); memset(digest, 'd', sizeof(digest)); if (sig == NULL) { goto error; } // BIGNUMからバイナリ値への変換 rlen = BN_num_bytes(sig->r); slen = BN_num_bytes(sig->s); if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { DSA_SIG_free(sig); goto error; } memset(sigblob, 0, SIGBLOB_LEN); BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); DSA_SIG_free(sig); // setting s = get_sshname_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_append_length(msg, sigblob, sizeof(sigblob)); len = buffer_len(msg); // setting *siglen = len; *sigptr = malloc(len); if (*sigptr == NULL) { goto error; } memcpy(*sigptr, buffer_ptr(msg), len); break; } case KEY_ECDSA256: // ECDSA case KEY_ECDSA384: case KEY_ECDSA521: { ECDSA_SIG *sig; const EVP_MD *evp_md; EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE]; u_int len, dlen, nid; buffer_t *buf2 = NULL; nid = keytype_to_hash_nid(keypair->type); if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { goto error; } EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa); memset(digest, 'd', sizeof(digest)); if (sig == NULL) { goto error; } buf2 = buffer_init(); if (buf2 == NULL) { // TODO: error check goto error; } buffer_put_bignum2(buf2, sig->r); buffer_put_bignum2(buf2, sig->s); ECDSA_SIG_free(sig); s = get_sshname_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2)); buffer_free(buf2); len = buffer_len(msg); *siglen = len; *sigptr = malloc(len); if (*sigptr == NULL) { goto error; } memcpy(*sigptr, buffer_ptr(msg), len); break; } case KEY_ED25519: ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen); if (ret != 0) goto error; break; default: buffer_free(msg); return FALSE; break; } buffer_free(msg); return TRUE; error: buffer_free(msg); return FALSE; }
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_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; } buffer_put_cstring(b, comment); }
// SHA-1(160bit)/SHA-256(256bit)を求める unsigned char *kex_dh_gex_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 kexgex_min, int kexgex_bits, int kexgex_max, BIGNUM *kexgex_p, BIGNUM *kexgex_g, BIGNUM *client_dh_pub, BIGNUM *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); // DH group sizeのビット数を加算する buffer_put_int(b, kexgex_min); buffer_put_int(b, kexgex_bits); buffer_put_int(b, kexgex_max); // DH鍵の素数と生成元を加算する buffer_put_bignum2(b, kexgex_p); buffer_put_bignum2(b, kexgex_g); buffer_put_bignum2(b, client_dh_pub); buffer_put_bignum2(b, 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; }
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; 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; } buffer_put_cstring(b, comment); }