Windowsçšã®CSPãäœæããç§å¯ã¯
ãYu.SãZyryanovã®èšäºã§æããã«
ãããŠããŸã ã
GOSTãã·ã¢ã®æå·åã¢ã«ãŽãªãºã ã¯ã
OpenSSL Gostã«å®è£
ãããŠã
ãŸã ã
ã€ã³ã¿ãŒãããäžã§ã誰ããäžèšã®ããŒã«ã䜿çšããŠWindowsçšã®GOSTæå·ãããã€ããŒã€ã³ã¿ãŒãã§ã€ã¹ãäœæãããšãã確èªãèŠã€ããããšãã§ããªãã£ãããšã«é©ããŠããŸãã
ããšãã°ã次ã®ãããªæ
å ±ã»ãã¥ãªãã£ã®è±å¯ãªçµéšãæã€å€§äŒæ¥ã®ã¿ããã®ã¿ã¹ã¯ãå®è¡ã§ãããšèãããããããŸããã
å°ãªããšãéšåçã«åè«ããããã«ããã®å£°æã¯ãã®èšäºã®ã¿ã¹ã¯ã«ãªããŸãã
ãŸããå³ã«ç€ºãããã«ãæšæºã®WindowsããŒã«ã䜿çšããŠGOST蚌ææžã®æŽåæ§ãæ€èšŒã§ããããã«ããŸãã ç°¡åã«ãããããEDSã®äœæã«ã€ããŠã¯èæ
®ãããããŒçæã®ãããã¯ã«ã€ããŠã¯è§ŠããŸããã ããžã¿ã«çœ²åãšããã·ã¥é¢æ°ãé€ãããããã€ããŒã®ãã¹ãŠã®å Žæã§ãMicrosoftã®äŸã§æ¢ã«è¿ãããŠããTRUEãªã©ã®åœ¢åŒã®ã¹ã¿ãã䜿çšãããŸãã èè
ã¯ãæå·ãããã€ããŒã®äœæã«é¢ãããããã¯ã«é¢ããäžé£ã®èšäºãæžãäºå®ã§ãããå°æ¥ãããã®æ¬ ç¹ã¯ãã¹ãŠè§£æ¶ãããŸãã
æåã®æ®µéã§ã¯ãããã»ã©å€ããè¡ãå¿
èŠã¯ãããŸãããã€ãŸããæåã«Yu.S. Zyryanovã®èšäºã«èšèŒãããŠããæé ãå®è¡ãã
RFC-4357ããOIDãªã¹ããååŸããGOSTæå·åã¢ã«ãŽãªãºã ã®å®è£
ã«é¢ããOpenSSLã©ã€ãã©ãªãã³ã³ãã€ã«ããæåŸã«ã
ã«ãŒã蚌ææžã ãã§ãªããå®éã®
CAã«ãŒã蚌ææžãååŸããŸããã
ããã§ã¯å§ããŸãããã
ãœãŒã¹ãããŠã³ããŒã
æåã«ãç·è²ã®[ä»ããããŠã³ããŒã]ãã¿ã³ãã¯ãªãã¯ããŠã
Microsoftæå·åãµãŒãã¹ãããã€ããŒéçºããããããŠã³ããŒãããå¿
èŠããããŸãã
éæ¥çãªãªã³ã¯ããaã³ããŸãããCSPDKããµã€ã
www.microsoft.comã§èŠã€ãããŸããã§ããã ãµã€ãããåé€ãããããã§ãäžèšã®ãªã³ã¯ã«ã¯2001幎以éã®å€ãããŒãžã§ã³ãå«ãŸããŠããŸãããããã§ãç§ãã¡ã«ã¯éåžžã«é©ããŠããŸãã ããŠã³ããŒãããŠè§£åããåŸããœãŒã¹ã§csp.cãã¡ã€ã«ãèŠã€ããxyzcsp.defããã³xyzcsp.rcã§ããããå€æŽããããã«xyzcsp.cã«ååãå€æŽããŸãïŒcsp.defããã³csp.rcïŒã
次ã«ã
OpenSSLã©ã€ãã©ãªãããŠã³ããŒãã
ãŸã ã å·çæç¹ã§ã¯ãããŒãžã§ã³ã¯1.0.0eã§ãã
æå·ãããã€ããŒxyzcsp.dllã®ç»é²
æå·åãããã€ããŒãã¬ãžã¹ããªã«ç»é²ããŸãã ãããè¡ãã«ã¯ãã³ãã³ããregedit xyzcsp.regãã䜿çšããŠæ¬¡ã®ãã¡ã€ã«ãïŒç®¡çè
æš©éã§ïŒå®è¡ããŸã
ãã¡ã€ã«xyzcsp.regïŒ
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider\XYZ Provider] "Image Path"="xyzcsp.dll" "Type"=dword:0000007B [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider Types\Type 123] "Name"="XYZ Provider" [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo] [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.2.643.2.2.19!1] "Name"="GOST R 34.10-2001" "Algid"=dword:00002036 "ExtraInfo"=hex:00,00,00,00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.2.643.2.2.3!2] "Name"="GOST R 34.11/34.10-2001" "Algid"=dword:00008037 "ExtraInfo"=hex:36,20,00,00,00,00,00,00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 1\CryptDllConvertPublicKeyInfo] [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 1\CryptDllConvertPublicKeyInfo\1.2.643.2.2.19] "Dll"="xyzcsp.dll" "FuncName"="xyz_ConvertPublicKeyInfo" [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 1\CryptDllConvertPublicKeyInfo\1.2.643.2.2.98] "Dll"="xyzcsp.dll" "FuncName"="xyz_ConvertPublicKeyInfo"
OpenSSLã©ã€ãã©ãª
ãœãŒã¹ããã®OpenSSLã®ã¢ã»ã³ããªã¯èå°è£ã«æ®ããŸããé£ããããšã§ã¯ãªãããšã«æ³šæããŠãã ãã
ãperlãšMS Visual Studioãã€ã³ã¹ããŒã«ããå¿
èŠããããŸããã³ã³ãã€ã«ããã«ã¯ãInstall.W32ãã¡ã€ã«ã®æ瀺ã«åŸãå¿
èŠããããŸãããã®åŸããã£ã¬ã¯ããªCã«ç§»åããŸãïŒ \ tmp32dllã¯ãªããžã§ã¯ããã¡ã€ã«ã®ã»ããã§ãããç°¡åã«ããããã«ãããžã§ã¯ãã§äœ¿çšãã1ã€ã®openssl.libãã¡ã€ã«ã«éããŸããã
ãã¡ã€ã«flist.txtïŒ
bf_buff.obj aes_core.obj aes_wrap.obj ameth_lib.obj asn1_gen.obj asn1_lib.obj asn1_par.obj asn_mime.obj asn_moid.obj asn_pack.obj a_bitstr.obj a_bool.obj a_bytes.obj a_d2i_fp.obj a_digest.obj a_dup.obj a_enum.obj a_gentm.obj a_i2d_fp.obj a_int.obj a_mbstr.obj a_object.obj a_octet.obj a_print.obj a_set.obj a_sign.obj a_strex.obj a_strnid.obj a_time.obj a_type.obj a_utctm.obj a_utf8.obj a_verify.obj bio_asn1.obj bio_b64.obj bio_cb.obj bio_enc.obj bio_err.obj bio_lib.obj bio_md.obj bio_ndef.obj bio_ok.obj bio_pk7.obj bio_ssl.obj bn_add.obj bn_asm.obj bn_blind.obj bn_const.obj bn_ctx.obj bn_depr.obj bn_div.obj bn_err.obj bn_exp.obj bn_exp2.obj bn_gcd.obj bn_gf2m.obj bn_kron.obj bn_lib.obj bn_mod.obj bn_mont.obj bn_mpi.obj bn_mul.obj bn_nist.obj bn_prime.obj bn_print.obj bn_rand.obj bn_recp.obj bn_shift.obj bn_sqr.obj bn_sqrt.obj bn_word.obj bss_dgram.obj bss_fd.obj bss_file.obj bss_log.obj bss_mem.obj bss_null.obj bss_sock.obj buffer.obj buf_err.obj by_dir.obj by_file.obj b_dump.obj b_print.obj b_sock.obj ca.obj camellia.obj cbc128.obj cbc_cksm.obj cbc_enc.obj cfb128.obj cfb64ede.obj cfb64enc.obj cfb_enc.obj ciphers.obj cmll_cbc.obj cmll_cfb.obj cmll_ctr.obj cmll_ecb.obj cmll_misc.obj cmll_ofb.obj cms.obj cms_asn1.obj cms_att.obj cms_cd.obj cms_dd.obj cms_enc.obj cms_env.obj cms_err.obj cms_ess.obj cms_io.obj cms_lib.obj cms_sd.obj cms_smime.obj comp_err.obj comp_lib.obj conf_api.obj conf_def.obj conf_err.obj conf_lib.obj conf_mall.obj conf_mod.obj conf_sap.obj cpt_err.obj crl.obj crl2p7.obj cryptlib.obj ctr128.obj cts128.obj cversion.obj c_all.obj c_allc.obj c_alld.obj c_cfb64.obj c_ecb.obj c_enc.obj c_ofb64.obj c_rle.obj c_skey.obj c_zlib.obj d1_both.obj d1_clnt.obj d1_enc.obj d1_lib.obj d1_meth.obj d1_pkt.obj d1_srvr.obj d2i_pr.obj d2i_pu.obj des_enc.obj des_old.obj des_old2.obj dgst.obj dh.obj dhparam.obj dh_ameth.obj dh_asn1.obj dh_check.obj dh_depr.obj dh_err.obj dh_gen.obj dh_key.obj dh_lib.obj dh_pmeth.obj dh_prn.obj digest.obj dsa.obj dsaparam.obj dsa_ameth.obj dsa_asn1.obj dsa_depr.obj dsa_err.obj dsa_gen.obj dsa_key.obj dsa_lib.obj dsa_ossl.obj dsa_pmeth.obj dsa_prn.obj dsa_sign.obj dsa_vrf.obj dso_beos.obj dso_dl.obj dso_dlfcn.obj dso_err.obj dso_lib.obj dso_null.obj dso_openssl.obj dso_vms.obj dso_win32.obj ebcdic.obj ec.obj ec2_mult.obj ec2_smpl.obj ecb3_enc.obj ecb_enc.obj ech_err.obj ech_key.obj ech_lib.obj ech_ossl.obj eck_prn.obj ecparam.obj ecp_mont.obj ecp_nist.obj ecp_smpl.obj ecs_asn1.obj ecs_err.obj ecs_lib.obj ecs_ossl.obj ecs_sign.obj ecs_vrf.obj ec_ameth.obj ec_asn1.obj ec_check.obj ec_curve.obj ec_cvt.obj ec_err.obj ec_key.obj ec_lib.obj ec_mult.obj ec_pmeth.obj ec_print.obj ede_cbcm_enc.obj enc.obj encode.obj enc_read.obj enc_writ.obj engine.obj eng_all.obj eng_cnf.obj eng_cryptodev.obj eng_ctrl.obj eng_dyn.obj eng_err.obj eng_fat.obj eng_init.obj eng_lib.obj eng_list.obj eng_openssl.obj eng_pkey.obj eng_table.obj err.obj errstr.obj err_all.obj err_prn.obj evp_acnf.obj evp_asn1.obj evp_enc.obj evp_err.obj evp_key.obj evp_lib.obj evp_pbe.obj evp_pkey.obj ex_data.obj e_aes.obj e_bf.obj e_camellia.obj e_cast.obj e_des.obj e_des3.obj e_gost_err.obj e_idea.obj e_null.obj e_old.obj e_rc2.obj e_rc4.obj e_rc5.obj e_seed.obj e_xcbc_d.obj fcrypt.obj fcrypt_b.obj f_enum.obj f_int.obj f_string.obj gendh.obj gendsa.obj genpkey.obj genrsa.obj gost2001.obj gost2001_keyx.obj gost89.obj gost94_keyx.obj gosthash.obj gost_ameth.obj gost_asn1.obj gost_crypt.obj gost_ctl.obj gost_eng.obj gost_keywrap.obj gost_md.obj gost_params.obj gost_pmeth.obj gost_sign.obj hmac.obj hm_ameth.obj hm_pmeth.obj i2d_pr.obj i2d_pu.obj i_cbc.obj i_cfb64.obj i_ecb.obj i_ofb64.obj i_skey.obj krb5_asn.obj kssl.obj lhash.obj lh_stats.obj md4_dgst.obj md4_one.obj md5_dgst.obj md5_one.obj mdc2dgst.obj mdc2_one.obj md_rand.obj mem.obj mem_clr.obj mem_dbg.obj m_dss.obj m_dss1.obj m_ecdsa.obj m_md4.obj m_md5.obj m_mdc2.obj m_null.obj m_ripemd.obj m_sha.obj m_sha1.obj m_sigver.obj m_wp.obj names.obj nseq.obj nsseq.obj n_pkey.obj obj_dat.obj obj_err.obj obj_lib.obj obj_xref.obj ocsp.obj ocsp_asn.obj ocsp_cl.obj ocsp_err.obj ocsp_ext.obj ocsp_ht.obj ocsp_lib.obj ocsp_prn.obj ocsp_srv.obj ocsp_vfy.obj ofb128.obj ofb64ede.obj ofb64enc.obj ofb_enc.obj o_dir.obj o_names.obj o_str.obj o_time.obj p12_add.obj p12_asn.obj p12_attr.obj p12_crpt.obj p12_crt.obj p12_decr.obj p12_init.obj p12_key.obj p12_kiss.obj p12_mutl.obj p12_npas.obj p12_p8d.obj p12_p8e.obj p12_utl.obj p5_crpt.obj p5_crpt2.obj p5_pbe.obj p5_pbev2.obj p8_pkey.obj passwd.obj pcbc_enc.obj pcy_cache.obj pcy_data.obj pcy_lib.obj pcy_map.obj pcy_node.obj pcy_tree.obj pem_all.obj pem_err.obj pem_info.obj pem_lib.obj pem_oth.obj pem_pk8.obj pem_pkey.obj pem_seal.obj pem_sign.obj pem_x509.obj pem_xaux.obj pk12err.obj pk7_asn1.obj pk7_attr.obj pk7_doit.obj pk7_lib.obj pk7_mime.obj pk7_smime.obj pkcs12.obj pkcs7.obj pkcs7err.obj pkcs8.obj pkey.obj pkeyparam.obj pkeyutl.obj pmeth_fn.obj pmeth_gn.obj pmeth_lib.obj pqueue.obj prime.obj pvkfmt.obj p_dec.obj p_enc.obj p_lib.obj p_open.obj p_seal.obj p_sign.obj p_verify.obj qud_cksm.obj rand.obj randfile.obj rand_egd.obj rand_err.obj rand_key.obj rand_lib.obj rand_nw.obj rand_os2.obj rand_unix.obj rand_win.obj rc2cfb64.obj rc2ofb64.obj rc2_cbc.obj rc2_ecb.obj rc2_skey.obj rc4_enc.obj rc4_skey.obj read2pwd.obj req.obj rmd_dgst.obj rmd_one.obj rpc_enc.obj rsa.obj rsautl.obj rsa_ameth.obj rsa_asn1.obj rsa_chk.obj rsa_depr.obj rsa_eay.obj rsa_err.obj rsa_gen.obj rsa_lib.obj rsa_none.obj rsa_null.obj rsa_oaep.obj rsa_pk1.obj rsa_pmeth.obj rsa_prn.obj rsa_pss.obj rsa_saos.obj rsa_sign.obj rsa_ssl.obj rsa_x931.obj s23_clnt.obj s23_lib.obj s23_meth.obj s23_pkt.obj s23_srvr.obj s2_clnt.obj s2_enc.obj s2_lib.obj s2_meth.obj s2_pkt.obj s2_srvr.obj s3_both.obj s3_clnt.obj s3_enc.obj s3_lib.obj s3_meth.obj s3_pkt.obj s3_srvr.obj seed.obj seed_cbc.obj seed_cfb.obj seed_ecb.obj seed_ofb.obj sess_id.obj set_key.obj sha1dgst.obj sha1_one.obj sha256.obj sha512.obj sha_dgst.obj sha_one.obj smime.obj speed.obj spkac.obj ssl_algs.obj ssl_asn1.obj ssl_cert.obj ssl_ciph.obj ssl_err.obj ssl_err2.obj ssl_lib.obj ssl_rsa.obj ssl_sess.obj ssl_stat.obj ssl_txt.obj stack.obj str2key.obj s_cb.obj s_client.obj s_server.obj s_socket.obj s_time.obj t1_clnt.obj t1_enc.obj t1_lib.obj t1_meth.obj t1_reneg.obj t1_srvr.obj tasn_dec.obj tasn_enc.obj tasn_fre.obj tasn_new.obj tasn_prn.obj tasn_typ.obj tasn_utl.obj tb_asnmth.obj tb_cipher.obj tb_dh.obj tb_digest.obj tb_dsa.obj tb_ecdh.obj tb_ecdsa.obj tb_pkmeth.obj tb_rand.obj tb_rsa.obj tb_store.obj ts.obj ts_asn1.obj ts_conf.obj ts_err.obj ts_lib.obj ts_req_print.obj ts_req_utils.obj ts_rsp_print.obj ts_rsp_sign.obj ts_rsp_utils.obj ts_rsp_verify.obj ts_verify_ctx.obj txt_db.obj t_bitst.obj t_crl.obj t_pkey.obj t_req.obj t_spki.obj t_x509.obj t_x509a.obj uid.obj ui_compat.obj ui_err.obj ui_lib.obj ui_openssl.obj ui_util.obj uplink.obj v3err.obj v3_addr.obj v3_akey.obj v3_akeya.obj v3_alt.obj v3_asid.obj v3_bcons.obj v3_bitst.obj v3_conf.obj v3_cpols.obj v3_crld.obj v3_enum.obj v3_extku.obj v3_genn.obj v3_ia5.obj v3_info.obj v3_int.obj v3_lib.obj v3_ncons.obj v3_ocsp.obj v3_pci.obj v3_pcia.obj v3_pcons.obj v3_pku.obj v3_pmaps.obj v3_prn.obj v3_purp.obj v3_skey.obj v3_sxnet.obj v3_utl.obj verify.obj version.obj wp_block.obj wp_dgst.obj x509.obj x509cset.obj x509name.obj x509rset.obj x509spki.obj x509type.obj x509_att.obj x509_cmp.obj x509_d2.obj x509_def.obj x509_err.obj x509_ext.obj x509_lu.obj x509_obj.obj x509_r2x.obj x509_req.obj x509_set.obj x509_trs.obj x509_txt.obj x509_v3.obj x509_vfy.obj x509_vpm.obj xcbc_enc.obj x_algor.obj x_all.obj x_attrib.obj x_bignum.obj x_crl.obj x_exten.obj x_info.obj x_long.obj x_name.obj x_nx509.obj x_pkey.obj x_pubkey.obj x_req.obj x_sig.obj x_spki.obj x_val.obj x_x509.obj x_x509a.obj
ãã®ãããªé·ããªã¹ãããaã³ããŸããããã®libãã¡ã€ã«ã®ã©ã®objãã¡ã€ã«ãã¢ã»ã³ããªã«å¿
èŠã§ãã©ããäžèŠããèŠã€ããç°¡åãªæ¹æ³ãããããŸããã ããããã¡ã€ã«ãäœæããŠã圹ã«ç«ããªããããtmp32dllãã£ã¬ã¯ããªã«ããã»ãŒå®å
šãªobjãã¡ã€ã«ã®ãªã¹ãã䜿çšããå¿
èŠããããŸããã
make_lib.batã³ãã³ãã§openssl.libãäœæããŸã
make_lib.batïŒ
call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" lib /out:openssl.lib @flist.txt
å¿
èŠãªããã·ã¥é¢æ°ã®äœæãéå§ããGOSTã«åŸã£ãŠããžã¿ã«çœ²åãæ€èšŒããŸãããã
ããããããããmy_hash_gostïŒïŒããã³my_verify_gostïŒïŒãšåŒã³ãŸãã ããããååŸããã«ã¯ãæ¢è£œã®OpenSSLããã¹ãã䜿çšããŸããããç¹ã«ããŒã¿ã®ãããªãããããã€ãé ã®å€æŽãè¡ãå Žåãããã·ã¥ãå転ããå¿
èŠã¯ãããŸãããããã以å€ã®ãã¹ãŠããããã°ããã«ã¯ããããã°ã«æéãããããŸããã ãå
¬ééµãšããžã¿ã«çœ²åãå«ã-å¿
èŠã
å°ãæŽå²ã æåã«ãmy_verify_gosté¢æ°ã¯ã32ãã€ããã¹ãŠã®å®æ°ã«çããããã·ã¥ã§ãã¹ããããŸããã ãããŠããã¯ç§ãæã£ãã é¢æ°ã¯ååã«éãåäœããŸããããããªãã©ã³ãã ãªãã€ãã»ããã§æ§æãããå®éã®ããã·ã¥ãæ¿å
¥ããããšããã®çŽåŸã«ããžã¿ã«çœ²åã®ãã§ãã¯ãåæ¢ããŸããã é·ãéãç§ã¯å®æ°ããã·ã¥ããã©ãŒãªã³ã°ãããŠããããšãç解ã§ããŸããã§ããã®ã§ãé¢æ°ãå転ããã«æ©èœããã®ã«é©ããŠããŸãã ãã¹ããå®éã®ããã·ã¥ã§éå§ãããå Žåã幞éãªããšã«ãOpenSSLã©ã€ãã©ãªã¯EDS蚌ææžããã§ãã¯ããããã«èšå®ããã®ã«ååå°é£ã§ãã
ãã¹ãŠã®#includeã®çŽåŸã«ãããã®è¡ãxyzcsp.cãã¡ã€ã«ã«è²Œãä»ããŸã
#include "gosthash.h" #include "gost_lcl.h" static void perevorot_buf(unsigned char *obj, int k) { char buf[64]; int i; for( i = 0; i < k; i++ ) buf[i] = obj[k-1-i]; memcpy(obj, buf, k); } static int pkey_gost01_cp_verify(EC_KEY* pub_key, const unsigned char *sig, size_t siglen, unsigned char *tbs, size_t tbs_len) { int ok = 0; DSA_SIG *s=unpack_cp_signature(sig,siglen); if (!s) return 0; if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,pub_key); DSA_SIG_free(s); return ok; } int my_verify_gost(char *in_hash, const BYTE *in_sign, char *in_pub1, char *in_pub2, int nid) { int res, errcode; EC_KEY *eckey = NULL; unsigned char sig[64], tbs[32]; int siglen=64, tbs_len=32; BIGNUM *X=NULL,*Y=NULL; char perevorot_pub[32]; EC_POINT *pub_key; // memcpy(tbs, in_pub1, 32); perevorot_buf(tbs, 32); X= getbnfrombuf((const unsigned char*)tbs,32); memcpy(tbs, in_pub2, 32); perevorot_buf(tbs, 32); Y= getbnfrombuf((const unsigned char*)tbs,32); memcpy(tbs, in_hash, 32); // ! perevorot_buf(tbs, 32); memcpy(sig, in_sign, 64); perevorot_buf(sig, 64); // if (!(eckey = EC_KEY_new())) { errcode = 1; goto err_exit; } if (!fill_GOST2001_params(eckey, nid)) { errcode = 2; goto err_exit; } if (!(pub_key = EC_POINT_new(EC_KEY_get0_group(eckey)))) { errcode = 3; goto err_exit; } if (!EC_POINT_set_affine_coordinates_GFp(EC_KEY_get0_group(eckey) ,pub_key,X,Y,NULL)) { errcode = 4; goto err_exit; } if (!EC_KEY_set_public_key(eckey,pub_key)) { errcode = 5; goto err_exit; } if (!pkey_gost01_cp_verify(eckey, sig, siglen, tbs, tbs_len)) { errcode = 6; goto err_exit; } else errcode = 0; //success err_exit: if (pub_key) EC_POINT_free(pub_key); if (X) BN_free(X); if (Y) BN_free(Y); if (eckey) EC_KEY_free(eckey); return errcode; } void my_hash_gost(const BYTE *buf, int buflen, char *hash_res) { gost_subst_block *b= &GostR3411_94_CryptoProParamSet; gost_hash_ctx ctx; init_gost_hash_ctx(&ctx,b); start_hash(&ctx); hash_block(&ctx,buf,buflen); finish_hash(&ctx,(byte *)hash_res); } // char hash_gost[32]; char hash_sha1[20]; char public_key[64];
XYZãããã€ããŒ
æåŸã«ããããã€ããŒã®é¢åãèŠãŠã¿ãŸãããã 圌ã®ååãéžæããŠãã ããïŒ "XYZ Provider"ã ãããã£ãŠãã¡ã€ã³ãã¡ã€ã«ã¯xyzcsp.cãšåŒã°ããxyzcsp.defãã¡ã€ã«ãšxyzcsp.rcãã¡ã€ã«ãå¿
èŠã§ãã
csp.cãã¡ã€ã«ã®CSPDKã«ããå
ã®ãµã³ãã«ã§ã¯ãââé¢æ°CPAcquireContextãCPHashDataãCPGetHashParamãCPVerifySignatureã®ã¿ã«é¢å¿ããããŸãã ãããããããã€ããŒã®ãã³ãã«ãããã·ã¥é¢æ°ãäœæããããžã¿ã«çœ²åããã§ãã¯ããããã®é¢æ°ã§ããããšã¯ç°¡åã«ããããŸãã ãããã®é¢æ°ã以äžã®é¢æ°ã«çœ®ãæããŸãã
ãããã«å ããŠãxyz_ConvertPublicKeyInfoãšããåªããé¢æ°ã1ã€äœæããŸãããã®é¢æ°ã¯ãããžã¿ã«çœ²åã®å
¬éããŒã®å€æã«é¢äžããŸãã xyz_ConvertPublicKeyInfoãxyzcsp.defãã¡ã€ã«ã«è¿œå ããŠããªã³ã«ãŒããã®ååããšã¯ã¹ããŒãããããšãå¿ããªãã§ãã ããã å€æã¯ãå
¬éããŒè¡šèšã®ASN1ã¬ã³ãŒãã®æåã®2ãã€ããç¡èŠããããšã§æ§æãããŸããããã«ããããããã32ãã€ãã®ååã®ããŒãçŽç²ãªåœ¢åŒã§ååŸãããŸãã
DllMainé¢æ°ãšãxyzcsp.cããå€ãCPAcquireContextãCPHashDataãCPGetHashParamãCPVerifySignatureãåé€ããxyzcsp.defããå»æ¢ãããDESCRIPTIONã³ãã³ããšååDllRegisterServerããã³DllUnregisterServerãåé€ããŸãããã
xyzcsp.cããã¡ã€ã«ã®æåŸã«è¿œå ããŸãã
BOOL WINAPI CPAcquireContext( OUT HCRYPTPROV *phProv, IN LPCSTR szContainer, IN DWORD dwFlags, IN PVTableProvStruc pVTable) { *phProv = 123; return TRUE; } BOOL WINAPI CPHashData( IN HCRYPTPROV hProv, IN HCRYPTHASH hHash, IN CONST BYTE *pbData, IN DWORD cbDataLen, IN DWORD dwFlags) { my_hash_gost(pbData, cbDataLen, hash_gost); SHA1(pbData, cbDataLen, hash_sha1); return TRUE; } BOOL WINAPI CPGetHashParam( IN HCRYPTPROV hProv, IN HCRYPTHASH hHash, IN DWORD dwParam, OUT LPBYTE pbData, IN OUT LPDWORD pcbDataLen, IN DWORD dwFlags) { switch(dwParam) { case HP_HASHVAL: if(*pcbDataLen == 20) // sha1 { memcpy(pbData, hash_sha1, 20); break; } default: *pcbDataLen = 0; SetLastError(E_INVALIDARG); return FALSE; } return TRUE; } BOOL WINAPI CPVerifySignature( IN HCRYPTPROV hProv, IN HCRYPTHASH hHash, IN CONST BYTE *pbSignature, IN DWORD cbSigLen, IN HCRYPTKEY hPubKey, IN LPCWSTR szDescription, IN DWORD dwFlags) { #define NTE_IC_ERROR_PREDEF 0x89900000L INT err; err = my_verify_gost(hash_gost, pbSignature, public_key, public_key+32, NID_id_GostR3410_2001_CryptoPro_A_ParamSet); if ( err ) { SetLastError( NTE_IC_ERROR_PREDEF | err ); return FALSE; } return TRUE; } BOOL WINAPI xyz_ConvertPublicKeyInfo( DWORD dwCertEncodingType, VOID *EncodedKeyInfo, DWORD dwAlg, DWORD dwFlags, BYTE** ppStructInfo, DWORD* StructLen ) { memcpy(public_key, ((CERT_PUBLIC_KEY_INFO*)EncodedKeyInfo)->PublicKey.pbData + 2, 64); return TRUE; }
æå·ãããã€ããŒã®ãœãŒã¹ã«ã€ããŠè©³ããã³ã¡ã³ãããå¿
èŠã¯ãªããšæããŸãã ãã¹ãŠã¯ããã¹ãããæããã§ãã
ãã¹ãããã°ã©ã ãæžã
å¥ã®ãã¹ãããã°ã©ã ãå¿
èŠãªã®ã¯ãªãã§ããïŒ ãã¹ãã®å®è¡ã«å ããŠãADVAPI32.dllã®SystemFunction035é¢æ°ãšCRYPT32.dllã®I_CryptGetDefaultCryptProvããæ£ãããããŒãžã§ã³ã«å€æŽããããã«ã·ã¹ãã ã«ããããé©çšããŸãã ãã®ããã°ã©ã ã¯ãWindows XPãšWindows 7ã®äž¡æ¹ã§æ£åžžã«åäœããŸãã
èšäºã®æåŸã«ãWindows XP SP3ã§ã·ã¹ãã ãã¡ã€ã«ã«ããããé©çšããæ¹æ³ã瀺ãããŠããŸãããã®å Žåãç¹å¥ãªãã¹ãããã°ã©ã ã¯å¿
èŠãããŸããã
ãã¡ã€ã«testcsp.cppïŒ
#include "stdafx.h" #include <windows.h> #include <wincrypt.h> typedef HCRYPTPROV (WINAPI *pI_CryptGetDefaultCryptProv)(ALG_ID algid); HCRYPTPROV hProv = NULL; typedef int (__stdcall *def_CryptExtOpenCER)( HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow); def_CryptExtOpenCER CryptExtOpenCER; typedef int (__stdcall *def_MyProc)(void); def_MyProc MyProc; #define PATCH_NUM 2 char *patch_list[2*PATCH_NUM]={ "ADVAPI32.dll","SystemFunction035", "CRYPT32.dll","I_CryptGetDefaultCryptProv" }; void WriteMem(int pos, char *patch, int len) { DWORD my_id = GetCurrentProcessId(); HANDLE p_hand = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, NULL, my_id); if (WriteProcessMemory(p_hand, (LPDWORD)pos, patch, len, NULL)==0) { printf("Error write to memory\nHint: run from Administrator rigths"); } CloseHandle(p_hand); } HCRYPTPROV PASCAL old_I_CryptGetDefaultCryptProv(int AlgID) //call MS Provider { __asm mov eax,0; //, 10 __asm mov eax,0; return NULL; } HCRYPTPROV PASCAL my_I_CryptGetDefaultCryptProv(int AlgID) { if (AlgID!=0 && AlgID!=0x2036) return old_I_CryptGetDefaultCryptProv(AlgID); //old MS return hProv; } int StartPatch(void) { BYTE *p; HMODULE h_dll; char buf[10]; DWORD new_addr; for(int i=0;i<PATCH_NUM;i++) { h_dll = LoadLibrary(patch_list[i*2]); if (h_dll==NULL) { printf("Error! Can not LoadLibrary(%s)\n", patch_list[i*2]); return 1; } MyProc = (def_MyProc)GetProcAddress(h_dll, patch_list[i*2+1]); if (MyProc==NULL) { printf("Error! Can not GetProcAddress(%s)\n", patch_list[i*2+1]); return 1; } p = (BYTE*)MyProc; if (i==1) { memcpy(buf, p, 5); buf[5]=0xe9; new_addr = (DWORD)p; new_addr -= (DWORD)old_I_CryptGetDefaultCryptProv; new_addr -= 5; memcpy(buf+6, &new_addr, 4); WriteMem((DWORD)old_I_CryptGetDefaultCryptProv, buf, 10); buf[0]=0xe9; new_addr = (DWORD)my_I_CryptGetDefaultCryptProv; new_addr -= (DWORD)MyProc; new_addr -= 5; memcpy(buf+1, &new_addr, 4); WriteMem((DWORD)MyProc, buf, 5); } else { WriteMem((int)p, "\xb8\x01\x00\x00\x00\xC2\x04\x00", 8); //mov ax,1 - ret 4 } } return 0; } int RunCert(char *certName) { HMODULE h_dll; h_dll = LoadLibrary("C:\\windows\\system32\\CRYPTEXT.dll"); if (h_dll==NULL) return 1; CryptExtOpenCER = (def_CryptExtOpenCER)GetProcAddress(h_dll, "CryptExtOpenCER"); if (CryptExtOpenCER==NULL) return 2; CryptExtOpenCER(NULL, NULL, certName, SW_SHOW); FreeLibrary(h_dll); return 0; } int _tmain(int argc, _TCHAR* argv[]) { if (StartPatch()) { printf("Error Patch\n"); return 1; } if (RCRYPT_FAILED(CryptAcquireContext(&hProv, "test", NULL, 123, 0))) { printf("CryptAcquireConext returned error %x\n", GetLastError()); printf("FAILED\n"); return 1; } printf("SUCCEED\n"); RunCert("gnivc_2006.cer"); RunCert("rootsber.cer"); return 0; }
ãã¡ã€ã«ç·šé
ãããã€ããŒã³ã³ãã€ã«ãã¡ã€ã«comp_xyzcsp.batïŒ
call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" cl /I"..\include" /nologo /MT /O2 /c xyzcsp.c rc /I"..\include" xyzcsp.rc link /SUBSYSTEM:WINDOWS",5.0" /NODEFAULTLIB /DLL /DEF:xyzcsp.def /MACHINE:x86 /OUT:xyzcsp.dll xyzcsp.obj openssl.lib advapi32.lib kernel32.lib msvcrt.lib gdi32.lib user32.lib xyzcsp.res copy xyzcsp.dll ..\testcsp\ rem copy xyzcsp.dll c:\windows\system32
ãã¹ãã³ã³ãã€ã«ãã¡ã€ã«comp_test.batïŒ
call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" cl /I"..\include" testcsp.cpp advapi32.lib
ãã¹ã蚌ææž
gnivc_2006.cerãã¡ã€ã«ã«ã¯ãé£éŠçšåãµãŒãã¹ã®ã«ãŒã蚌ææžãå«ãŸããŠããŸãã
-----BEGIN CERTIFICATE----- MIIDGjCCAsegAwIBAgIQPx2a1ZtKRIBLiHKukksltTAKBgYqhQMCAgMFADCBwDEe MBwGCSqGSIb3DQEJARYPdWNpbmZvQGduaXZjLnJ1MQswCQYDVQQGEwJSVTEVMBMG A1UEBwwM0JzQvtGB0LrQstCwMTAwLgYDVQQKDCfQpNCT0KPQnyDQk9Cd0JjQktCm INCk0J3QoSDQoNC+0YHRgdC40LgxMDAuBgNVBAsMJ9Cj0LTQvtGB0YLQvtCy0LXR gNGP0Y7RidC40Lkg0YbQtdC90YLRgDEWMBQGA1UEAxMNR05JVkMgRk5TIFJVUzAe Fw0wNjA5MjcwOTI5NTdaFw0xMjA5MjcwOTM4MjdaMIHAMR4wHAYJKoZIhvcNAQkB Fg91Y2luZm9AZ25pdmMucnUxCzAJBgNVBAYTAlJVMRUwEwYDVQQHDAzQnNC+0YHQ utCy0LAxMDAuBgNVBAoMJ9Ck0JPQo9CfINCT0J3QmNCS0KYg0KTQndChINCg0L7R gdGB0LjQuDEwMC4GA1UECwwn0KPQtNC+0YHRgtC+0LLQtdGA0Y/RjtGJ0LjQuSDR htC10L3RgtGAMRYwFAYDVQQDEw1HTklWQyBGTlMgUlVTMGMwHAYGKoUDAgITMBIG ByqFAwICIwEGByqFAwICHgEDQwAEQCzY8VGw9ged02ijaj2KWOMXJVvzY1FEcg7G xedUtKx0wqyTVti0kmodEmm2cVfAbDkp0xAdBS9/mdDfeIrKXLajgZYwgZMwCwYD VR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBMQt5JPv+eiD7j1 nYkVJssQ6/RfMBAGCSsGAQQBgjcVAQQDAgEAMEIGCCsGAQUFBwEBBDYwNDAyBggr BgEFBQcwAoYmaHR0cDovL3d3dy5nbml2Yy5ydS91Yy9HTklWQ0ZOU1JVUy5jcnQw CgYGKoUDAgIDBQADQQDgEyWPI+fdXXiTYMLHdV76v8kVFIxCHCYtastcvZiM3cG1 wTFhio8fDx6sLgHHriOwQFg0zRUYHIs9nZEptLvM -----END CERTIFICATE-----
Sberbankã®ã«ãŒã蚌ææžãå«ãrootsber.cerãã¡ã€ã«ïŒ
-----BEGIN CERTIFICATE----- MIIDKjCCAtmgAwIBAgIGMDBDQT0HMAgGBiqFAwICAzCBwTELMAkGA1UEBhMCUlUx LTArBgNVBAoMJNCh0LHQtdGA0LHQsNC90Log0KDQvtGB0YHQuNC4INCe0JDQnjE4 MDYGA1UECwwv0JTQtdC/0LDRgNGC0LDQvNC10L3RgiDQsdC10LfQvtC/0LDRgdC9 0L7RgdGC0LgxJjAkBgNVBAMMHdCh0LHQtdGA0LHQsNC90Log0KDQvtGB0YHQuNC4 MSEwHwYJKoZIhvcNAQkBFhJjYXNicmZAc2JlcmJhbmsucnUwHhcNMDkwODA1MDAw MDAwWhcNMTcwODA1MDAwMDAwWjCBwTELMAkGA1UEBhMCUlUxLTArBgNVBAoMJNCh 0LHQtdGA0LHQsNC90Log0KDQvtGB0YHQuNC4INCe0JDQnjE4MDYGA1UECwwv0JTQ tdC/0LDRgNGC0LDQvNC10L3RgiDQsdC10LfQvtC/0LDRgdC90L7RgdGC0LgxJjAk BgNVBAMMHdCh0LHQtdGA0LHQsNC90Log0KDQvtGB0YHQuNC4MSEwHwYJKoZIhvcN AQkBFhJjYXNicmZAc2JlcmJhbmsucnUwYzAcBgYqhQMCAhMwEgYHKoUDAgIjAgYH KoUDAgIeAQNDAARAaYzyi29YQ9NC5cb/kq//J1kKhOgcvGWqsQu50mldjADTGfrl JUVXwu4fMUTHoF9TjY0O1kgrLYWT/kI4jABAWKOBsjCBrzAdBgNVHQ4EFgQUZmHo Zo41vw/U74ZlC8k/bcQODuowDAYDVR0TBAUwAwEB/zAzBgNVHR8ELDAqMCigJqAk hiJodHRwOi8vd3d3LnNicmYucnUvY2EvMDAwMHg1MDkuY3JsMAsGA1UdDwQEAwIC hDA+BgcqhQMDewMBBDMMMTAwQ0ExODUzetCa0L7RgNC90LXQstC+0Lkg0LrQu9GO 0Ycg0KPQpiDQodCRINCg0KQwCAYGKoUDAgIDA0EAD9Umnh/EZgjgQvpypdVwe0wa GnTi+dHhVwoNAX1tquxQNbAptbBs2OKzkRU7/mrBfDD4EdVV5xC1f2DTcH8NAg== -----END CERTIFICATE-----
äœæ¥çµæ
ãã¹ãããã°ã©ã ãå®è¡ãããšãçµæãåŸãããŸãã
æåŸã®é害ãåãé€ãããã«ãæšå¥šãããããã«ã蚌ææžãä¿¡é Œã§ãããã®ã®ãªã¹ãã«å«ããŸãã ãããè¡ãã«ã¯ã[蚌ææžã®ã€ã³ã¹ããŒã«]ãã¿ã³ãã¯ãªãã¯ãã[次ãž]ãæ°åã¯ãªãã¯ããŸãã ãã¹ãã®æåŸã«ãã·ã¹ãã ãå±éºã«ããããªãããã«ãä¿¡é Œãããã«ãŒãã¹ãã¢ãããã¹ã蚌ææžãåé€ããå¿
èŠããããŸãã
ãã¹ããåéããåŸãå¥ã®ç»åã芳å¯ããŸãã
åä¿¡ã«å¿
èŠãªãã®ã
Sberbankã«ãŒã蚌ææž
Sberbankã®èšŒææžã§ã¯ããããè¡ãããšã¯ã§ããŸããã
ããã¯ãSberbankãRFC 4357ã®å®æ°Bãã€ãŸãGostR3410_2001_CryptoPro_B_ParamSetã䜿çšããŠããããã§ãã
次ã«ãCPVerifySignatureé¢æ°ã®xyzcsp.cãã¡ã€ã«ã§å®æ°AãBã«å€æŽããŸããã€ãŸããmy_verify_gostãåŒã³åºããšãã«ãNID_id_GostR3410_2001_CryptoPro_B_ParamSetãã©ã¡ãŒã¿ãŒã䜿çšããŸãã
ãããã€ããŒãã³ã³ãã€ã«ããŠãã¹ããéå§ããåŸãå察ã®ç¶æ³ã芳å¯ããŸããé£éŠçšå眲ã®èšŒææžã¯æ€èšŒãããŠããããSberbankã¯æ£åžžã«æ©èœããŠããŸãã ããã¯å€§ããªæ¬ ç¹ã®ããã«æããŸãããæãåçŽãªæå·ãããã€ããŒã«ãšã£ãŠã¯ããã¯èš±ãããŸããã
ãã¡ããããã®ãªãã·ã§ã³ã¯å¯èœã§ãã2ã€ã®EDSãäžåºŠã«ãã§ãã¯ããå°ãªããšã1ã€ãåæããå ŽåãEDSãæ£ããããšã宣èšããŸãããããã¯æ ¹æ¬çã«ééã£ãŠããŸãã å
¬ééµã®OIDã調ã¹ãããããæ¥åæ²ç·ã®å¿
é ãã©ã¡ãŒã¿ãŒãæ¢ãå¿
èŠããããŸãã
çŸåšãå
¬éã®æºåäžã®æ¬¡ã®èšäºã§ã¯ããã®ç¶æ³ãåé¿ããæ¹æ³ã詳现ã«æ€èšããããŸããŸãªãã©ã¡ãŒã¿ãŒã䜿çšããŠEDSããŒãäœæããé¢æ°ãäœæããŸãã
ãŠãããŒãµã«ããããäœæãã
çµè«ãšããŠããŠãããŒãµã«ãããã®äœæã«é¢ããããã€ãã®èšèã
Windows XP SP3ã®å Žåã次ã®ãã¡ã€ã«ã眮ãæããã ãã§ãã
cïŒ\ windows \ system32 \ advapi32.dll
cïŒ\ windows \ system32 \ dllcache \ advapi32.dll
cïŒ\ windows \ system32 \ crypt32.dll
cïŒ\ windows \ system32 \ dllcache \ crypt32.dll
ã·ã¹ãã 1ã解æŸãããããã«å¥ã®ãã£ã¹ã¯ããèµ·åããŠããããé©çšããå¿
èŠããããŸãïŒãªã«ããªã¢ãŒãã§Windowsèµ·åãã£ã¹ã¯ããã§ããŸãïŒã次ã«ãsystem32ãã£ã¬ã¯ããªãšã³ããŒãä¿åãããŠããsystem32 \ dllcacheã®äž¡æ¹ã§ããã2ã€ã®ãã¡ã€ã«ã眮ãæããŸãã ãã¡ã€ã«ã¯ãããã¯ã¢ããããããŠãããå€æŽã§ããªããããå®è¡äžã®ã·ã¹ãã ã§ã®ãããé©çšã¯æ©èœããŸããã
ãã®åŸãæå·åãããã€ããŒxyzcsp.dllãå«ããã¡ã€ã«ããã£ã¬ã¯ããªcïŒ\ windows \ system32ã«ã³ããŒããŠãã·ã¹ãã ãæ€åºã§ããããã«ããããšãå¿ããªãã§ãã ããã
ããã§ã蚌ææžãã¯ãªãã¯ãããšãç¹å¥ãªããã°ã©ã ãèµ·åããã«ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§çŽæ¥ãã§ãã¯ãããŸãã
ãã¡ã€ã«ãããããé©çšããããŒãžã§ã³ã«çœ®ãæããŸãã
advapi32.dll C:\xyzcsp\PATCH\ADVAPI32.DLL 00017585: 8B B8 00017586: FF 01 00017587: 55 00 00017588: 8B 00 00017589: EC 00 0001758A: 81 C2 0001758B: EC 04 0001758C: 50 00 crypt32.dll C:\xyzcsp\PATCH\CRYPT32.DLL 00008F66: 8B E9 00008F67: FF 47 00008F68: 55 09 00008F69: 8B 00 00008F6A: EC 00 000098B2: 90 55 000098B3: 90 8B 000098B4: 90 EC 000098B5: 90 8B 000098B6: 90 45 000098B7: 90 08 000098B8: 53 83 000098B9: 00 F8 000098BA: 6F 00 000098BB: 00 74 000098BC: 66 21 000098BD: 00 3D 000098BE: 74 36 000098BF: 00 20 000098C0: 77 00 000098C2: 61 74 000098C3: 00 1A 000098C4: 72 3D 000098C5: 00 35 000098C6: 65 66 000098C8: 5C 00 000098C9: 00 74 000098CA: 50 13 000098CB: 00 3D 000098CC: 6F 37 000098CD: 00 80 000098CE: 6C 00 000098D0: 69 74 000098D1: 00 0C 000098D2: 63 3D 000098D3: 00 38 000098D4: 69 AA 000098D6: 65 00 000098D7: 00 74 000098D8: 73 05 000098D9: 00 E9 000098DA: 5C 8D 000098DB: 00 F6 000098DC: 4D FF 000098DD: 00 FF 000098DE: 69 6A 000098E0: 63 68 000098E1: 00 7B 000098E2: 72 00 000098E4: 6F 00 000098E5: 00 6A 000098E6: 73 00 000098E7: 00 8D 000098E8: 6F 05 000098E9: 00 40 000098EA: 66 A5 000098EB: 00 A7 000098EC: 74 77 000098ED: 00 50 000098EE: 5C 8D 000098EF: 00 45 000098F0: 53 08 000098F1: 00 50 000098F2: 79 FF 000098F3: 00 15 000098F4: 73 00 000098F5: 00 10 000098F6: 74 A7 000098F7: 00 77 000098F8: 65 83 000098F9: 00 F8 000098FA: 6D 00 000098FB: 00 74 000098FC: 43 DC 000098FD: 00 8B 000098FE: 65 45 000098FF: 00 08 00009900: 72 C9 00009901: 00 C2 00009902: 74 04
Windows 7ã®å ŽåããŠãããŒãµã«ããããäœæããããšãã§ããŸããåžæããå Žåã¯ãèªåã§ããããäœæããŠã¿ãŠãã ããã
GOSTæå·åãããã€ããŒãã€ã³ã¹ããŒã«ãããŠããå®éã®ã·ã¹ãã ã§ã¯ãéåžžãã·ã¹ãã DLLã®èªã¿èŸŒã¿ãç£èŠããŠãã®å Žã§ããããåœãŠãç¹å¥ãªPatchEngineãã©ã€ããŒãã€ã³ã¹ããŒã«ããããšã«ããããããã®åé¡ã解決ããŸãã
1ã€ã®ã¢ãŒã«ã€ãå
ã®ãã¹ãŠã®ãã¡ã€ã«
çµè«ãšããŠããã®èšäºã®ãã¹ãŠã®ãã¡ã€ã«ã1ã€ã®ã¢ãŒã«ã€ãã«ããŠã³ããŒãã§ãããªã³ã¯ãæäŸããŸãã
files.mail.ru/1OVVDB