int mm_answer_keyverify(int sock, Buffer *m) { Key *key; u_char *signature, *data, *blob; u_int signaturelen, datalen, bloblen; int verified = 0; int valid_data = 0; blob = buffer_get_string(m, &bloblen); signature = buffer_get_string(m, &signaturelen); data = buffer_get_string(m, &datalen); if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); key = key_from_blob(blob, bloblen); if (key == NULL) fatal("%s: bad public key blob", __func__); switch (key_blobtype) { case MM_USERKEY: valid_data = monitor_valid_userblob(data, datalen); break; case MM_HOSTKEY: valid_data = monitor_valid_hostbasedblob(data, datalen, hostbased_cuser, hostbased_chost); break; default: valid_data = 0; break; } if (!valid_data) fatal("%s: bad signature data blob", __func__); verified = key_verify(key, signature, signaturelen, data, datalen); debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); /* If auth was successful then record key to ensure it isn't reused */ if (verified == 1 && key_blobtype == MM_USERKEY) auth2_record_userkey(authctxt, key); else key_free(key); free(blob); free(signature); free(data); auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased"; monitor_reset_key_state(); buffer_clear(m); buffer_put_int(m, verified); mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); return (verified == 1); }
static int script_sign_hash(struct wallet *wallet, const uint160 *keyHash, const uint256 *hash, enum script_hash_type hashType, struct buff *script) { struct key *k; size_t siglen; uint8 *sig; bool s; k = wallet_lookup_pubkey(wallet, keyHash); if (k == NULL) { return 1; } s = key_sign(k, hash, sizeof *hash, &sig, &siglen); if (!s) { return 1; } Log(LGPFX " siglen=%zu\n", siglen); /* * Verify the signature is good. This code is new.. */ s = key_verify(k, hash, sizeof *hash, sig, siglen); ASSERT(s == 1); uint8 push_data[siglen + 1]; memcpy(push_data, sig, siglen); free(sig); push_data[siglen] = (uint8)hashType; script_push_data(script, push_data, siglen + 1); return 0; }
int dm2016_verify(struct ys_usb_handle *handle) { int res,i,ret,actual_length; unsigned char data[8],rxdata[8]; unsigned char decdata[8]; unsigned int headersize; unsigned int *head_ptr; unsigned char *buffer; get_random_bytes(data, 8); for(i = 0; i < 8; i ++) decdata[i] = data[i]; res = key_verify(decdata,0); if(res < 0) return -1; headersize = sizeof(struct usb_app_header); buffer = (unsigned char *)malloc(headersize+8); if(buffer==NULL){ //ysprint(); return -1; } memset(buffer,0,headersize+8); head_ptr = (unsigned int *)buffer; head_ptr[0] = CMD_DM2016_VERIFY; head_ptr[1] = 0; head_ptr[2] = 0; head_ptr[3] = 0; memcpy(buffer+headersize,decdata,8); usb_write(handle,buffer,headersize+8); free(buffer); buffer = NULL; //等待dsp返回 ret = libusb_bulk_transfer(handle->libusb_handle,handle->Endpoint_in,rxdata,sizeof(rxdata),&actual_length,5000); if(ret<0){ return ret; }else{ if(actual_length!=8) return -99; if(strncmp((const char *)rxdata,(const char *)data,8)==0) return 0; else return -98; } }
void kexdh_client(Kex *kex) { BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; DH *dh; Key *server_host_key; u_char *server_host_key_blob = NULL, *signature = NULL; u_char *kbuf, *hash; u_int klen, slen, sbloblen, hashlen; int kout; /* generate and send 'e', client DH public key */ switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: dh = dh_new_group1(); break; case KEX_DH_GRP14_SHA1: dh = dh_new_group14(); break; default: fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); } dh_gen_key(dh, kex->we_need * 8); packet_start(SSH2_MSG_KEXDH_INIT); packet_put_bignum2(dh->pub_key); packet_send(); debug("sending SSH2_MSG_KEXDH_INIT"); #ifdef DEBUG_KEXDH DHparams_print_fp(stderr, dh); fprintf(stderr, "pub= "); BN_print_fp(stderr, dh->pub_key); fprintf(stderr, "\n"); #endif debug("expecting SSH2_MSG_KEXDH_REPLY"); packet_read_expect(SSH2_MSG_KEXDH_REPLY); /* key, cert */ server_host_key_blob = packet_get_string(&sbloblen); server_host_key = key_from_blob(server_host_key_blob, sbloblen); if (server_host_key == NULL) fatal("cannot decode server_host_key_blob"); if (server_host_key->type != kex->hostkey_type) fatal("type mismatch for decoded server_host_key_blob"); if (kex->verify_host_key == NULL) fatal("cannot verify server_host_key"); if (kex->verify_host_key(server_host_key) == -1) fatal("server_host_key verification failed"); /* DH parameter f, server public DH key */ if ((dh_server_pub = BN_new()) == NULL) fatal("dh_server_pub == NULL"); packet_get_bignum2(dh_server_pub); #ifdef DEBUG_KEXDH fprintf(stderr, "dh_server_pub= "); BN_print_fp(stderr, dh_server_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_server_pub)); #endif /* signed H */ signature = packet_get_string(&slen); packet_check_eom(); if (!dh_pub_is_valid(dh, dh_server_pub)) packet_disconnect("bad server public DH value"); klen = DH_size(dh); kbuf = xmalloc(klen); if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0) fatal("DH_compute_key: failed"); #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif if ((shared_secret = BN_new()) == NULL) fatal("kexdh_client: BN_new failed"); if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) fatal("kexdh_client: BN_bin2bn failed"); memset(kbuf, 0, klen); free(kbuf); /* calc and verify H */ kex_dh_hash( kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), buffer_ptr(&kex->peer), buffer_len(&kex->peer), server_host_key_blob, sbloblen, dh->pub_key, dh_server_pub, shared_secret, &hash, &hashlen ); free(server_host_key_blob); BN_clear_free(dh_server_pub); DH_free(dh); if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) fatal("key_verify failed for server_host_key"); key_free(server_host_key); free(signature); /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } kex_derive_keys(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); }
static int userauth_pubkey(Authctxt *authctxt) { Buffer b; Key *key = NULL; char *pkalg; u_char *pkblob, *sig; u_int alen, blen, slen; int have_sig, pktype; int authenticated = 0; if (!authctxt->valid) { debug2("userauth_pubkey: disabled because of invalid user"); return 0; } have_sig = packet_get_char(); if (datafellows & SSH_BUG_PKAUTH) { debug2("userauth_pubkey: SSH_BUG_PKAUTH"); /* no explicit pkalg given */ pkblob = packet_get_string(&blen); buffer_init(&b); buffer_append(&b, pkblob, blen); /* so we have to extract the pkalg from the pkblob */ pkalg = buffer_get_string(&b, &alen); buffer_free(&b); } else { pkalg = packet_get_string(&alen); pkblob = packet_get_string(&blen); } pktype = key_type_from_name(pkalg); if (pktype == KEY_UNSPEC) { /* this is perfectly legal */ logit("userauth_pubkey: unsupported public key algorithm: %s", pkalg); goto done; } key = key_from_blob(pkblob, blen); if (key == NULL) { error("userauth_pubkey: cannot decode key: %s", pkalg); goto done; } if (key->type != pktype) { error("userauth_pubkey: type mismatch for decoded key " "(received %d, expected %d)", key->type, pktype); goto done; } if (have_sig) { sig = packet_get_string(&slen); packet_check_eom(); buffer_init(&b); if (datafellows & SSH_OLD_SESSIONID) { buffer_append(&b, session_id2, session_id2_len); } else { buffer_put_string(&b, session_id2, session_id2_len); } /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, authctxt->user); buffer_put_cstring(&b, datafellows & SSH_BUG_PKSERVICE ? "ssh-userauth" : authctxt->service); if (datafellows & SSH_BUG_PKAUTH) { buffer_put_char(&b, have_sig); } else { buffer_put_cstring(&b, "publickey"); buffer_put_char(&b, have_sig); buffer_put_cstring(&b, pkalg); } buffer_put_string(&b, pkblob, blen); #ifdef DEBUG_PK buffer_dump(&b); #endif /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) authenticated = 1; buffer_free(&b); xfree(sig); } else { debug("test whether pkalg/pkblob are acceptable"); packet_check_eom(); /* XXX fake reply and always send PK_OK ? */ /* * XXX this allows testing whether a user is allowed * to login: if you happen to have a valid pubkey this * message is sent. the message is NEVER sent at all * if a user is not allowed to login. is this an * issue? -markus */ if (PRIVSEP(user_key_allowed(authctxt->pw, key))) { packet_start(SSH2_MSG_USERAUTH_PK_OK); packet_put_string(pkalg, alen); packet_put_string(pkblob, blen); packet_send(); packet_write_wait(); authctxt->postponed = 1; } } if (authenticated != 1) auth_clear_options(); done: debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); if (key != NULL) key_free(key); xfree(pkalg); xfree(pkblob); return authenticated; }
static int userauth_hostbased(Authctxt *authctxt) { Buffer b; Key *key = NULL; char *pkalg, *cuser, *chost, *service; u_char *pkblob, *sig; u_int alen, blen, slen; int pktype; int authenticated = 0; if (!authctxt->valid) { debug2("userauth_hostbased: disabled because of invalid user"); return 0; } pkalg = packet_get_string(&alen); pkblob = packet_get_string(&blen); chost = packet_get_string(NULL); cuser = packet_get_string(NULL); sig = packet_get_string(&slen); debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d", cuser, chost, pkalg, slen); #ifdef DEBUG_PK debug("signature:"); buffer_init(&b); buffer_append(&b, sig, slen); buffer_dump(&b); buffer_free(&b); #endif pktype = key_type_from_name(pkalg); if (pktype == KEY_UNSPEC) { /* this is perfectly legal */ logit("userauth_hostbased: unsupported " "public key algorithm: %s", pkalg); goto done; } key = key_from_blob(pkblob, blen); if (key == NULL) { error("userauth_hostbased: cannot decode key: %s", pkalg); goto done; } if (key->type != pktype) { error("userauth_hostbased: type mismatch for decoded key " "(received %d, expected %d)", key->type, pktype); goto done; } service = datafellows & SSH_BUG_HBSERVICE ? __UNCONST("ssh-userauth") : authctxt->service; buffer_init(&b); buffer_put_string(&b, session_id2, session_id2_len); /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, authctxt->user); buffer_put_cstring(&b, service); buffer_put_cstring(&b, "hostbased"); buffer_put_string(&b, pkalg, alen); buffer_put_string(&b, pkblob, blen); buffer_put_cstring(&b, chost); buffer_put_cstring(&b, cuser); #ifdef DEBUG_PK buffer_dump(&b); #endif /* test for allowed key and correct signature */ authenticated = 0; if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) authenticated = 1; buffer_free(&b); done: debug2("userauth_hostbased: authenticated %d", authenticated); if (key != NULL) key_free(key); xfree(pkalg); xfree(pkblob); xfree(cuser); xfree(chost); xfree(sig); return authenticated; }
void kexecdh_client(Kex *kex) { EC_KEY *client_key; EC_POINT *server_public; const EC_GROUP *group; BIGNUM *shared_secret; Key *server_host_key; u_char *server_host_key_blob = NULL, *signature = NULL; u_char *kbuf, *hash; u_int klen, slen, sbloblen, hashlen; if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) fatal("%s: EC_KEY_new_by_curve_name failed", __func__); if (EC_KEY_generate_key(client_key) != 1) fatal("%s: EC_KEY_generate_key failed", __func__); group = EC_KEY_get0_group(client_key); packet_start(SSH2_MSG_KEX_ECDH_INIT); packet_put_ecpoint(group, EC_KEY_get0_public_key(client_key)); packet_send(); debug("sending SSH2_MSG_KEX_ECDH_INIT"); #ifdef DEBUG_KEXECDH fputs("client private key:\n", stderr); key_dump_ec_key(client_key); #endif debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY); /* hostkey */ server_host_key_blob = packet_get_string(&sbloblen); server_host_key = key_from_blob(server_host_key_blob, sbloblen); if (server_host_key == NULL) fatal("cannot decode server_host_key_blob"); if (server_host_key->type != kex->hostkey_type) fatal("type mismatch for decoded server_host_key_blob"); if (kex->verify_host_key == NULL) fatal("cannot verify server_host_key"); if (kex->verify_host_key(server_host_key) == -1) fatal("server_host_key verification failed"); /* Q_S, server public key */ if ((server_public = EC_POINT_new(group)) == NULL) fatal("%s: EC_POINT_new failed", __func__); packet_get_ecpoint(group, server_public); if (key_ec_validate_public(group, server_public) != 0) fatal("%s: invalid server public key", __func__); #ifdef DEBUG_KEXECDH fputs("server public key:\n", stderr); key_dump_ec_point(group, server_public); #endif /* signed H */ signature = packet_get_string(&slen); packet_check_eom(); klen = (EC_GROUP_get_degree(group) + 7) / 8; kbuf = xmalloc(klen); if (ECDH_compute_key(kbuf, klen, server_public, client_key, NULL) != (int)klen) fatal("%s: ECDH_compute_key failed", __func__); #ifdef DEBUG_KEXECDH dump_digest("shared secret", kbuf, klen); #endif if ((shared_secret = BN_new()) == NULL) fatal("%s: BN_new failed", __func__); if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) fatal("%s: BN_bin2bn failed", __func__); memset(kbuf, 0, klen); free(kbuf); /* calc and verify H */ kex_ecdh_hash( kex->evp_md, group, kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), buffer_ptr(&kex->peer), buffer_len(&kex->peer), server_host_key_blob, sbloblen, EC_KEY_get0_public_key(client_key), server_public, shared_secret, &hash, &hashlen ); free(server_host_key_blob); EC_POINT_clear_free(server_public); EC_KEY_free(client_key); if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) fatal("key_verify failed for server_host_key"); key_free(server_host_key); free(signature); /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } kex_derive_keys(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); }
static int userauth_pubkey(Authctxt *authctxt) { Buffer b; Key *key = NULL; char *pkalg, *userstyle; u_char *pkblob, *sig; u_int alen, blen, slen; int have_sig, pktype; int authenticated = 0; if (!authctxt->valid) { debug2("userauth_pubkey: disabled because of invalid user"); return 0; } have_sig = packet_get_char(); if (datafellows & SSH_BUG_PKAUTH) { debug2("userauth_pubkey: SSH_BUG_PKAUTH"); /* no explicit pkalg given */ pkblob = packet_get_string(&blen); buffer_init(&b); buffer_append(&b, pkblob, blen); /* so we have to extract the pkalg from the pkblob */ pkalg = buffer_get_string(&b, &alen); buffer_free(&b); } else { pkalg = packet_get_string(&alen); pkblob = packet_get_string(&blen); } pktype = key_type_from_name(pkalg); if (pktype == KEY_UNSPEC) { /* this is perfectly legal */ logit("userauth_pubkey: unsupported public key algorithm: %s", pkalg); goto done; } key = key_from_blob(pkblob, blen); if (key == NULL) { error("userauth_pubkey: cannot decode key: %s", pkalg); goto done; } if (key->type != pktype) { error("userauth_pubkey: type mismatch for decoded key " "(received %d, expected %d)", key->type, pktype); goto done; } if (key_type_plain(key->type) == KEY_RSA && (datafellows & SSH_BUG_RSASIGMD5) != 0) { logit("Refusing RSA key because client uses unsafe " "signature scheme"); goto done; } if (auth2_userkey_already_used(authctxt, key)) { logit("refusing previously-used %s key", key_type(key)); goto done; } if (match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types, strlen(options.pubkey_key_types), 0) != 1) { logit("%s: key type %s not in PubkeyAcceptedKeyTypes", __func__, sshkey_ssh_name(key)); goto done; } if (have_sig) { sig = packet_get_string(&slen); packet_check_eom(); buffer_init(&b); if (datafellows & SSH_OLD_SESSIONID) { buffer_append(&b, session_id2, session_id2_len); } else { buffer_put_string(&b, session_id2, session_id2_len); } /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); buffer_put_cstring(&b, userstyle); free(userstyle); buffer_put_cstring(&b, datafellows & SSH_BUG_PKSERVICE ? "ssh-userauth" : authctxt->service); if (datafellows & SSH_BUG_PKAUTH) { buffer_put_char(&b, have_sig); } else { buffer_put_cstring(&b, "publickey"); buffer_put_char(&b, have_sig); buffer_put_cstring(&b, pkalg); } buffer_put_string(&b, pkblob, blen); #ifdef DEBUG_PK buffer_dump(&b); #endif pubkey_auth_info(authctxt, key, NULL); /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) { authenticated = 1; /* Record the successful key to prevent reuse */ auth2_record_userkey(authctxt, key); key = NULL; /* Don't free below */ } buffer_free(&b); free(sig); } else { debug("test whether pkalg/pkblob are acceptable"); packet_check_eom(); /* XXX fake reply and always send PK_OK ? */ /* * XXX this allows testing whether a user is allowed * to login: if you happen to have a valid pubkey this * message is sent. the message is NEVER sent at all * if a user is not allowed to login. is this an * issue? -markus */ if (PRIVSEP(user_key_allowed(authctxt->pw, key))) { packet_start(SSH2_MSG_USERAUTH_PK_OK); packet_put_string(pkalg, alen); packet_put_string(pkblob, blen); packet_send(); packet_write_wait(); authctxt->postponed = 1; } } if (authenticated != 1) auth_clear_options(); done: debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); if (key != NULL) key_free(key); free(pkalg); free(pkblob); return authenticated; }
static int userauth_pubkey(Authctxt *authctxt) { #ifdef WIN32_FIXME int loginStat = 1; char currentUser[MAX_PATH] = {0}; DWORD currentUserSize = sizeof(currentUser); int targetIsCurrent = 0; # ifdef USE_NTCREATETOKEN int doOpenSSHVerify = 1; # else int doOpenSSHVerify = 0; # endif #endif Buffer b; Key *key = NULL; char *pkalg, *userstyle; u_char *pkblob, *sig; u_int alen, blen, slen; int have_sig, pktype; int authenticated = 0; if (!authctxt->valid) { debug2("userauth_pubkey: disabled because of invalid user"); return 0; } have_sig = packet_get_char(); if (datafellows & SSH_BUG_PKAUTH) { debug2("userauth_pubkey: SSH_BUG_PKAUTH"); /* no explicit pkalg given */ pkblob = packet_get_string(&blen); buffer_init(&b); buffer_append(&b, pkblob, blen); /* so we have to extract the pkalg from the pkblob */ pkalg = buffer_get_string(&b, &alen); buffer_free(&b); } else { pkalg = packet_get_string(&alen); pkblob = packet_get_string(&blen); } pktype = key_type_from_name(pkalg); if (pktype == KEY_UNSPEC) { /* this is perfectly legal */ logit("userauth_pubkey: unsupported public key algorithm: %s", pkalg); goto done; } key = key_from_blob(pkblob, blen); if (key == NULL) { error("userauth_pubkey: cannot decode key: %s", pkalg); goto done; } if (key->type != pktype) { error("userauth_pubkey: type mismatch for decoded key " "(received %d, expected %d)", key->type, pktype); goto done; } if (key_type_plain(key->type) == KEY_RSA && (datafellows & SSH_BUG_RSASIGMD5) != 0) { logit("Refusing RSA key because client uses unsafe " "signature scheme"); goto done; } if (auth2_userkey_already_used(authctxt, key)) { logit("refusing previously-used %s key", key_type(key)); goto done; } if (match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types, 0) != 1) { logit("%s: key type %s not in PubkeyAcceptedKeyTypes", __func__, sshkey_ssh_name(key)); goto done; } if (have_sig) { sig = packet_get_string(&slen); packet_check_eom(); buffer_init(&b); if (datafellows & SSH_OLD_SESSIONID) { buffer_append(&b, session_id2, session_id2_len); } else { buffer_put_string(&b, session_id2, session_id2_len); } /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); buffer_put_cstring(&b, userstyle); free(userstyle); buffer_put_cstring(&b, datafellows & SSH_BUG_PKSERVICE ? "ssh-userauth" : authctxt->service); if (datafellows & SSH_BUG_PKAUTH) { buffer_put_char(&b, have_sig); } else { buffer_put_cstring(&b, "publickey"); buffer_put_char(&b, have_sig); buffer_put_cstring(&b, pkalg); } buffer_put_string(&b, pkblob, blen); #ifdef DEBUG_PK buffer_dump(&b); #endif pubkey_auth_info(authctxt, key, NULL); /* test for correct signature */ authenticated = 0; /* * On pure win32 try to logon using lsa first. */ #ifdef WIN32_FIXME authctxt -> hTokenLsa_ = NULL; authctxt -> methoddata = NULL; /* * Retrieve name of current login user (i.e. sshd process owner). */ GetUserName(currentUser, ¤tUserSize); /* * Try to get token from lsa, but only if targetUser != currentUser. * Owerthise we already have targetUser's token in current thread, so * we only need key verify from original OpenSSH code. */ targetIsCurrent = (strcmp(currentUser, authctxt -> user) == 0); if (targetIsCurrent) { doOpenSSHVerify = 1; } else { loginStat = LsaLogon(&authctxt -> hTokenLsa_, HomeDirLsaW, authctxt -> user, pkblob, blen, sig, slen, buffer_ptr(&b), buffer_len(&b), datafellows); /* * If lsa logon process success. */ if (loginStat == 0) { /* * And user authorized OK. */ if (authctxt -> hTokenLsa_) { doOpenSSHVerify = 0; /* * This is part of openssh authorization needed for parsing * 'options' block in key. */ authctxt -> pw -> pw_dir = GetHomeDir(authctxt -> user); if (PRIVSEP(user_key_allowed(authctxt -> pw, key, 1))) // PRAGMA:TODO { authenticated = 1; } else { authenticated = 0; } buffer_free(&b); free(sig); } } } if (doOpenSSHVerify) { /* * If lsa fails, test for correct signature using openssh code. */ authctxt -> pw -> pw_dir = GetHomeDir(authctxt -> user); if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0)) //PRAGMA:TODO && PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) { authenticated = 1; } } /* * Original code. */ #else /* #ifdef WIN32_FIXME */ if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) { authenticated = 1; /* Record the successful key to prevent reuse */ auth2_record_userkey(authctxt, key); key = NULL; /* Don't free below */ } buffer_free(&b); free(sig); #endif /* else #ifdef WIN32_FIXME. */ } else { debug("test whether pkalg/pkblob are acceptable"); packet_check_eom(); /* XXX fake reply and always send PK_OK ? */ /* * XXX this allows testing whether a user is allowed * to login: if you happen to have a valid pubkey this * message is sent. the message is NEVER sent at all * if a user is not allowed to login. is this an * issue? -markus */ #ifndef WIN32_FIXME if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) #endif { packet_start(SSH2_MSG_USERAUTH_PK_OK); packet_put_string(pkalg, alen); packet_put_string(pkblob, blen); packet_send(); packet_write_wait(); authctxt->postponed = 1; } } if (authenticated != 1) auth_clear_options(); done: debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); if (key != NULL) key_free(key); free(pkalg); free(pkblob); return authenticated; }
void kexgex_client(Kex *kex) { BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; BIGNUM *p = NULL, *g = NULL; Key *server_host_key; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; u_int klen, slen, sbloblen, hashlen; int kout; int min, max, nbits; DH *dh; nbits = dh_estimate(kex->dh_need * 8); if (datafellows & SSH_OLD_DHGEX) { /* Old GEX request */ packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); packet_put_int(nbits); min = DH_GRP_MIN; max = DH_GRP_MAX; debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); } else { /* New GEX request */ min = DH_GRP_MIN; max = DH_GRP_MAX; packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); packet_put_int(min); packet_put_int(nbits); packet_put_int(max); debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent", min, nbits, max); } #ifdef DEBUG_KEXDH fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", min, nbits, max); #endif packet_send(); debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); if ((p = BN_new()) == NULL) fatal("BN_new"); packet_get_bignum2(p); if ((g = BN_new()) == NULL) fatal("BN_new"); packet_get_bignum2(g); packet_check_eom(); if (BN_num_bits(p) < min || BN_num_bits(p) > max) fatal("DH_GEX group out of range: %d !< %d !< %d", min, BN_num_bits(p), max); dh = dh_new_group(g, p); dh_gen_key(dh, kex->we_need * 8); #ifdef DEBUG_KEXDH DHparams_print_fp(stderr, dh); fprintf(stderr, "pub= "); BN_print_fp(stderr, dh->pub_key); fprintf(stderr, "\n"); #endif debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); /* generate and send 'e', client DH public key */ packet_start(SSH2_MSG_KEX_DH_GEX_INIT); packet_put_bignum2(dh->pub_key); packet_send(); debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); /* key, cert */ server_host_key_blob = packet_get_string(&sbloblen); server_host_key = key_from_blob(server_host_key_blob, sbloblen); if (server_host_key == NULL) fatal("cannot decode server_host_key_blob"); if (server_host_key->type != kex->hostkey_type) fatal("type mismatch for decoded server_host_key_blob"); if (kex->verify_host_key == NULL) fatal("cannot verify server_host_key"); if (kex->verify_host_key(server_host_key) == -1) fatal("server_host_key verification failed"); /* DH parameter f, server public DH key */ if ((dh_server_pub = BN_new()) == NULL) fatal("dh_server_pub == NULL"); packet_get_bignum2(dh_server_pub); #ifdef DEBUG_KEXDH fprintf(stderr, "dh_server_pub= "); BN_print_fp(stderr, dh_server_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_server_pub)); #endif /* signed H */ signature = packet_get_string(&slen); packet_check_eom(); if (!dh_pub_is_valid(dh, dh_server_pub)) packet_disconnect("bad server public DH value"); klen = DH_size(dh); kbuf = xmalloc(klen); if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0) fatal("DH_compute_key: failed"); #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif if ((shared_secret = BN_new()) == NULL) fatal("kexgex_client: BN_new failed"); if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) fatal("kexgex_client: BN_bin2bn failed"); explicit_bzero(kbuf, klen); free(kbuf); if (datafellows & SSH_OLD_DHGEX) min = max = -1; /* calc and verify H */ kexgex_hash( kex->hash_alg, kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), buffer_ptr(&kex->peer), buffer_len(&kex->peer), server_host_key_blob, sbloblen, min, nbits, max, dh->p, dh->g, dh->pub_key, dh_server_pub, shared_secret, &hash, &hashlen ); /* have keys, free DH */ DH_free(dh); free(server_host_key_blob); BN_clear_free(dh_server_pub); if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) fatal("key_verify failed for server_host_key"); key_free(server_host_key); free(signature); /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } kex_derive_keys_bn(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); }
static int verify_signature(struct key *key, FILE *fin) { struct gzip_header gh; struct gzip_xfield *gx; struct gzsig_data *gd; u_char *sig, digest[20], buf[8192], sbuf[4096]; SHA_CTX ctx; int i, siglen; /* Read gzip header. */ if ((i = fread((u_char *)&gh, 1, sizeof(gh), fin)) != sizeof(gh)) { fprintf(stderr, "Error reading gzip header: %s\n", strerror(errno)); return (-1); } /* Verify gzip header. */ if (memcmp(gh.magic, GZIP_MAGIC, sizeof(gh.magic)) != 0) { fprintf(stderr, "Invalid gzip file\n"); return (-1); } else if (gh.flags & GZIP_FCONT){ fprintf(stderr, "Multi-part gzip files not supported\n"); return (-1); } else if ((gh.flags & GZIP_FEXTRA) == 0) { fprintf(stderr, "No gzip signature found\n"); return (-1); } /* Read signature. */ gx = (struct gzip_xfield *)buf; if ((i = fread((u_char *)gx, 1, sizeof(*gx), fin)) != sizeof(*gx)) { fprintf(stderr, "Error reading extra field: %s\n", strerror(errno)); return (-1); } if (memcmp(gx->subfield.id, GZSIG_ID, sizeof(gx->subfield.id)) != 0) { fprintf(stderr, "Unknown extra field\n"); return (-1); } gx->subfield.len = letoh16(gx->subfield.len); if (gx->subfield.len <= 0 || gx->subfield.len > sizeof(sbuf)) { fprintf(stderr, "Invalid signature length\n"); return (-1); } gd = (struct gzsig_data *)sbuf; if ((i = fread((u_char *)gd, 1, gx->subfield.len, fin)) != gx->subfield.len) { fprintf(stderr, "Error reading signature: %s\n", strerror(errno)); return (-1); } /* Skip over any options. */ if (gh.flags & GZIP_FNAME) { if (skip_string(fin)) return (-1); } if (gh.flags & GZIP_FCOMMENT) { if (skip_string(fin)) return (-1); } if (gh.flags & GZIP_FENCRYPT && fread(buf, 1, GZIP_FENCRYPT_LEN, fin) != GZIP_FENCRYPT_LEN) return (-1); /* Check signature version. */ if (gd->version != GZSIG_VERSION) { fprintf(stderr, "Unknown signature version: %d\n", gd->version); return (-1); } /* Compute SHA1 checksum over compressed data and trailer. */ sig = (u_char *)(gd + 1); siglen = gx->subfield.len - sizeof(*gd); SHA1_Init(&ctx); while ((i = fread(buf, 1, sizeof(buf), fin)) > 0) { SHA1_Update(&ctx, buf, i); } SHA1_Final(digest, &ctx); /* Verify signature. */ if (key_verify(key, digest, sizeof(digest), sig, siglen) < 0) { fprintf(stderr, "Error verifying signature\n"); return (-1); } return (0); }
static void userauth_pubkey(Authctxt *authctxt) { Buffer b; Key *key = NULL; char *pkalg; u_char *pkblob, *sig; u_int alen, blen, slen; int have_sig, pktype; int authenticated = 0; if (!authctxt || !authctxt->method) fatal("%s: missing context", __func__); have_sig = packet_get_char(); if (datafellows & SSH_BUG_PKAUTH) { debug2("userauth_pubkey: SSH_BUG_PKAUTH"); /* no explicit pkalg given */ pkblob = packet_get_string(&blen); buffer_init(&b); buffer_append(&b, pkblob, blen); /* so we have to extract the pkalg from the pkblob */ pkalg = buffer_get_string(&b, &alen); buffer_free(&b); } else { pkalg = packet_get_string(&alen); pkblob = packet_get_string(&blen); } pktype = key_type_from_name(pkalg); if (pktype == KEY_UNSPEC) { /* this is perfectly legal */ log("userauth_pubkey: unsupported public key algorithm: %s", pkalg); goto done; } key = key_from_blob(pkblob, blen); if (key == NULL) { error("userauth_pubkey: cannot decode key: %s", pkalg); goto done; } if (key->type != pktype) { error("userauth_pubkey: type mismatch for decoded key " "(received %d, expected %d)", key->type, pktype); goto done; } /* Detect and count abandonment */ if (authctxt->method->method_data) { Key *prev_key; unsigned char *prev_pkblob; int prev_blen; /* * Check for earlier test of a key that was allowed but * not followed up with a pubkey req for the same pubkey * and with a signature. */ prev_key = authctxt->method->method_data; if ((prev_blen = key_to_blob(prev_key, &prev_pkblob, NULL))) { if (prev_blen != blen || memcmp(prev_pkblob, pkblob, blen) != 0) { authctxt->method->abandons++; authctxt->method->attempts++; } } key_free(prev_key); authctxt->method->method_data = NULL; } if (have_sig) { sig = packet_get_string(&slen); packet_check_eom(); buffer_init(&b); if (datafellows & SSH_OLD_SESSIONID) { buffer_append(&b, session_id2, session_id2_len); } else { buffer_put_string(&b, session_id2, session_id2_len); } /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, authctxt->user); buffer_put_cstring(&b, datafellows & SSH_BUG_PKSERVICE ? "ssh-userauth" : authctxt->service); if (datafellows & SSH_BUG_PKAUTH) { buffer_put_char(&b, have_sig); } else { buffer_put_cstring(&b, "publickey"); buffer_put_char(&b, have_sig); buffer_put_cstring(&b, pkalg); } buffer_put_string(&b, pkblob, blen); #ifdef DEBUG_PK buffer_dump(&b); #endif /* test for correct signature */ if (user_key_allowed(authctxt->pw, key) && key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) { authenticated = 1; } authctxt->method->postponed = 0; buffer_free(&b); xfree(sig); } else { debug("test whether pkalg/pkblob are acceptable"); packet_check_eom(); /* XXX fake reply and always send PK_OK ? */ /* * XXX this allows testing whether a user is allowed * to login: if you happen to have a valid pubkey this * message is sent. the message is NEVER sent at all * if a user is not allowed to login. is this an * issue? -markus */ if (user_key_allowed(authctxt->pw, key)) { packet_start(SSH2_MSG_USERAUTH_PK_OK); packet_put_string(pkalg, alen); packet_put_string(pkblob, blen); packet_send(); packet_write_wait(); authctxt->method->postponed = 1; /* * Remember key that was tried so we can * correctly detect abandonment. See above. */ authctxt->method->method_data = (void *) key; key = NULL; } } if (authenticated != 1) auth_clear_options(); done: /* * XXX TODO: add config options for specifying users for whom * this userauth is insufficient and what userauths may * continue. */ #ifdef USE_PAM if (authenticated) { if (!do_pam_non_initial_userauth(authctxt)) authenticated = 0; } #endif /* USE_PAM */ debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); if (key != NULL) key_free(key); xfree(pkalg); xfree(pkblob); #ifdef HAVE_CYGWIN if (check_nt_auth(0, authctxt->pw) == 0) return; #endif if (authenticated) authctxt->method->authenticated = 1; }
static int cuckoo_hash_get(struct cuckoo_filter_table *table, uint8_t *key, uint32_t *p_index) { int i, j; uint32_t tag[2], index; struct hash_slot_cache *slot; tag[0] = cuckoo_hash_lsb(key, table->bucket_num); tag[1] = cuckoo_hash_msb(key, table->bucket_num); #ifdef CUCKOO_DBG printf("get t0:%x t1:%x\n", tag[0], tag[1]); #endif dump_md5_key(key); /* Filter the key and verify if it exists. */ slot = table->buckets[tag[0]]; for (i = 0; i < ASSOC_WAY; i++) { if (cuckoo_hash_msb(key, table->bucket_num) == slot[i].tag) { if (slot[i].status == OCCUPIED) { index = slot[i].index; if (key_verify(key, index)) { if(p_index != NULL) *p_index = index; break; } } else if (slot[i].status == DELETED) { #ifdef CUCKOO_DBG printf("Key has been deleted!\n"); #endif return DELETED; } } } if (i == ASSOC_WAY) { slot = table->buckets[tag[1]]; for (j = 0; j < ASSOC_WAY; j++) { if (cuckoo_hash_lsb(key, table->bucket_num) == slot[j].tag) { if (slot[j].status == OCCUPIED) { index = slot[j].index; if (key_verify(key, index)) { if (p_index != NULL) *p_index = index; break; } } else if (slot[j].status == DELETED) { #ifdef CUCKOO_DBG printf("Key has been deleted!\n"); #endif return DELETED; } } } if (j == ASSOC_WAY) { #ifdef CUCKOO_DBG printf("Key not exists!\n"); #endif return AVAILIBLE; } } return OCCUPIED; }