📄 pubcrypt.c
字号:
int nid_sign_type; size_t digest_len; char errbuf[1024]; void *ref; if ( (!msg_str) || (!ret_buff) ) return -EINVAL; rc=pcrypt_crypt_refer_rsa_key(cap,&key); if (rc) return rc; msg_len=strlen(msg_str); rc=-ENOMEM; out=g_malloc(RSA_size(key)); if (!out) goto no_free_out; switch(sign_type) { case IPMSG_SIGN_MD5: nid_sign_type=NID_md5; digest_len=MD5_DIGEST_LEN; ref=MD5(msg_str, msg_len, hash); if (!ref) { rc=ERR_get_error(); err_out("Can not calculate MD5 hash value: err=%s\n", ERR_error_string(rc, errbuf)); rc=-rc; goto out_free_out; } break; case IPMSG_SIGN_SHA1: nid_sign_type=NID_sha1; digest_len=SHA1_DIGEST_LEN; ref=SHA1(msg_str, msg_len, hash); if (!ref) { rc=ERR_get_error(); err_out("Can not calculate SHA1 hash value: err=%s\n", ERR_error_string(rc, errbuf)); rc=-rc; goto out_free_out; } break; default: rc=-EINVAL; goto out_free_out; break; } rc=RSA_sign(nid_sign_type, hash, digest_len, out, &out_len, key); if (rc<0) goto out_free_out; rc=-ENOMEM; bn_hash=BN_new(); if (!bn_hash) goto out_free_out; ref=BN_bin2bn(out, out_len, bn_hash); if (!ref) { rc=ERR_get_error(); err_out("Can not convert binary key to BIGNUM: err=%s\n", ERR_error_string(rc, errbuf)); rc=-rc; goto bn_hash_free_out; } hash_string=BN_bn2hex(bn_hash); if (!hash_string) goto bn_hash_free_out; rc=0; *ret_buff=hash_string; bn_hash_free_out: if (bn_hash) BN_free(bn_hash); out_free_out: if (out) g_free(out); no_free_out: return rc;}int pcrypt_verify_sign(unsigned long cap,unsigned long sign_type,unsigned char *msg_str, unsigned char *sign,unsigned char *peer_e,unsigned char *peer_n){ int rc; RSA *key=NULL; BIGNUM *bn_sign=NULL; unsigned char *raw_sign; size_t msg_len; unsigned char hash[MD5SHA1_DIGEST_LEN]; int nid_sign_type; size_t digest_len; char errbuf[1024]; void *ref; if ( (!msg_str) || (!sign) || (!peer_e) || (!peer_n) ) return -EINVAL; rc=convert_peer_key(peer_e,peer_n,&key); if (rc) return rc; msg_len=strlen(msg_str); rc=-ENOMEM; /* *バイナリの署名を獲得 */ rc=BN_hex2bn(&bn_sign,sign); if (!rc) { rc=ERR_get_error(); err_out("Can not convert hex-key to BIGNUM: err=%s\n", ERR_error_string(rc, errbuf)); rc=-rc; goto bn_sign_free_out; } raw_sign=g_malloc(BN_num_bytes(bn_sign)); if (!raw_sign) goto bn_sign_free_out; rc=BN_bn2bin(bn_sign, raw_sign); if (rc != RSA_size(key)) { err_out("hash size is invalid\n"); goto raw_sign_free_out; } /* * タイミング攻撃対策 */ rc=RSA_blinding_on(key,NULL); if (!rc) { rc=ERR_get_error(); err_out("Can not make RSA key blind: err=%s\n", ERR_error_string(rc, errbuf)); rc=-rc; goto raw_sign_free_out; } switch(sign_type) { default: rc=-EINVAL; goto raw_sign_free_out; break; case IPMSG_SIGN_MD5: nid_sign_type=NID_md5; ref=MD5(msg_str, msg_len, hash); if (!rc) { rc=ERR_get_error(); err_out("Can not calculate MD5 hash value : err=%s\n", ERR_error_string(rc, errbuf)); rc=-rc; dbg_out("Verify with MD5 sign\n"); goto raw_sign_free_out; } digest_len=MD5_DIGEST_LEN; break; case IPMSG_SIGN_SHA1: nid_sign_type=NID_sha1; ref=SHA1(msg_str, msg_len, hash); if (!rc) { rc=ERR_get_error(); err_out("Can not calculate SHA1 hash value : err=%s\n", ERR_error_string(rc, errbuf)); rc=-rc; goto raw_sign_free_out; } digest_len=SHA1_DIGEST_LEN; dbg_out("Verify with SHA1 sign\n"); break; } rc=RSA_verify(nid_sign_type,hash,digest_len,raw_sign,RSA_size(key), key); if (!rc){ rc=ERR_get_error(); err_out("Sign invalid : err=%s\n", ERR_error_string(rc, errbuf)); rc=-rc; goto raw_sign_free_out; }else{ rc=0; } raw_sign_free_out: if (raw_sign) g_free(raw_sign); bn_sign_free_out: if (bn_sign) BN_free(bn_sign); free_key_out: if (key) { g_assert(key->n); g_assert(key->e); BN_free(key->n); BN_free(key->e); key->n=NULL; key->e=NULL; RSA_free(key); } no_free_out: return rc;}intpcrypt_get_key_filename(unsigned long key_name,char **pubkey,char **privkey) { int rc; size_t key_len,key_fname_len; RSA *rsa=NULL; size_t key_priv_fname_len; size_t key_pub_fname_len; char *pub_key_file=NULL; char *priv_key_file=NULL; int j; if ( (!pubkey) || (!privkey) ) return -EINVAL; rc=pcrypt_get_rsa_key_length(key_name,&key_len); if (rc) return rc; dbg_out("Key bits:%d\n", key_len); /* キー長をbit長で表した値の桁数を算出 */ for(j=key_len,key_fname_len=1;j;j/=10,++key_fname_len); /* +2 is seperator and null terminate */ key_priv_fname_len=strlen(RSA_PRIVKEY_FNAME_PREFIX) + key_fname_len+ 1; priv_key_file=g_malloc(key_priv_fname_len); if (!priv_key_file) return -EINVAL; key_pub_fname_len=strlen(RSA_PUBKEY_FNAME_PREFIX) + key_fname_len+ 1; pub_key_file=g_malloc(key_pub_fname_len); if (!pub_key_file) goto priv_key_file_free_out; snprintf(priv_key_file,key_priv_fname_len-1,"%s%d", RSA_PRIVKEY_FNAME_PREFIX, key_len); snprintf(pub_key_file,key_pub_fname_len-1,"%s%d", RSA_PUBKEY_FNAME_PREFIX, key_len); dbg_out("store files are Private-key:%s Public-key:%s\n", priv_key_file,pub_key_file); *pubkey=pub_key_file; *privkey=priv_key_file; return 0; pub_key_file_free_out: if (pub_key_file) g_free(pub_key_file); priv_key_file_free_out: if (priv_key_file) g_free(priv_key_file); return rc;}int pcrypt_store_rsa_key(unsigned long key_name,pem_password_cb *cb){ int rc; gchar *store_dir=NULL; char *home_dir=NULL; size_t key_len; RSA *rsa; int j; size_t key_fname_len; char *priv_key_file=NULL; char *pub_key_file=NULL; char *file_path=NULL; rc=get_envval("HOME",&home_dir); if (rc) goto no_free_out; store_dir=g_build_filename(home_dir,G2IPMSG_KEY_DIR,NULL); if (!store_dir) goto home_dir_free_out; rc=check_secure_directory(store_dir); if ( (rc) && (rc != -ENOENT) ) { err_out("Directory %s is not secure.\n",store_dir); goto store_dir_free_out; } if (rc == -ENOENT) { dbg_out("Directory %s does not exist.\n",store_dir); rc=mkdir(store_dir,S_IRWXU); if (rc){ rc=-errno; goto store_dir_free_out; } } dbg_out("Directory check:%s OK\n",store_dir); rc=pcrypt_crypt_refer_rsa_key(key_name,&rsa); if (rc) goto store_dir_free_out; rc=pcrypt_get_key_filename(key_name,&pub_key_file,&priv_key_file); if (rc) goto store_dir_free_out; /* * Private key */ key_fname_len = strlen(store_dir) + strlen(priv_key_file)+ 3; file_path=g_malloc(key_fname_len); if (!file_path) goto filename_free_out; snprintf(file_path, key_fname_len-1,"%s" G_DIR_SEPARATOR_S "%s", store_dir, priv_key_file); rc=store_private_key(file_path,rsa,cb); if (rc) goto filename_free_out; if (file_path) g_free(file_path); file_path=NULL; /* * Public key */ key_fname_len = strlen(store_dir) + strlen(pub_key_file)+ 3; file_path=g_malloc(key_fname_len); if (!file_path) goto filename_free_out; snprintf(file_path, key_fname_len-1,"%s" G_DIR_SEPARATOR_S "%s", store_dir, pub_key_file); rc=store_public_key(file_path,rsa); if (rc) goto filename_free_out; if (file_path) g_free(file_path); file_path=NULL; rc=0; filename_free_out: if (file_path) g_free(file_path); pub_key_file_free_out: if (pub_key_file) g_free(pub_key_file); if (priv_key_file) g_free(priv_key_file); store_dir_free_out: if (store_dir) g_free(store_dir); home_dir_free_out: if (home_dir) g_free(home_dir); no_free_out: return rc;}int pcrypt_load_rsa_key(unsigned long key_name,pem_password_cb *cb){ int rc; gchar *store_dir=NULL; char *home_dir=NULL; size_t key_len; RSA *rsa=NULL; int j; size_t key_fname_len; char *priv_key_file=NULL; char *pub_key_file=NULL; char *file_path=NULL; char errbuf[1024]; rc=get_envval("HOME",&home_dir); if (rc) goto no_free_out; store_dir=g_build_filename(home_dir,G2IPMSG_KEY_DIR,NULL); if (!store_dir) goto home_dir_free_out; rc=check_secure_directory(store_dir); if (rc) { err_out("Directory %s is not secure or does not exist.\n",store_dir); goto store_dir_free_out; } dbg_out("Directory check:%s OK\n",store_dir); rc=pcrypt_get_key_filename(key_name,&pub_key_file,&priv_key_file); if (rc) goto store_dir_free_out; /* * Private key */ key_fname_len = strlen(store_dir) + strlen(priv_key_file)+ 3; file_path=g_malloc(key_fname_len); if (!file_path) goto filename_free_out; snprintf(file_path, key_fname_len-1,"%s" G_DIR_SEPARATOR_S "%s", store_dir, priv_key_file); rc=load_private_key(file_path,&rsa,cb); if (rc) goto filename_free_out; if (file_path) g_free(file_path); file_path=NULL; /* * Public key */ key_fname_len = strlen(store_dir) + strlen(pub_key_file)+ 3; file_path=g_malloc(key_fname_len); if (!file_path) goto filename_free_out; snprintf(file_path, key_fname_len-1,"%s" G_DIR_SEPARATOR_S "%s", store_dir, pub_key_file); rc=load_public_key(file_path,&rsa); if (rc) goto filename_free_out; if (file_path) g_free(file_path); file_path=NULL; rc=RSA_check_key(rsa); if (!rc) { rc=ERR_get_error(); err_out("Invalid RSA key : err=%s\n", ERR_error_string(rc, errbuf)); rc=-rc; RSA_free(rsa); goto filename_free_out; } rc=pcrypt_crypt_set_rsa_key(key_name,rsa); if (rc) { RSA_free(rsa); goto filename_free_out; } rc=pcrypt_get_rsa_key_length(key_name,&key_len); g_assert(!rc); dbg_out("RSA key length: %d has been loaded successfully.\n",key_len); rc=0; filename_free_out: if (file_path) g_free(file_path); pub_key_file_free_out: if (pub_key_file) g_free(pub_key_file); if (priv_key_file) g_free(priv_key_file); store_dir_free_out: if (store_dir) g_free(store_dir); home_dir_free_out: if (home_dir) g_free(home_dir); no_free_out: return rc;}int select_asymmetric_key(unsigned long peer_cap,RSA *rsa,unsigned long *selected_key){ unsigned long candidates; int i; int rc; int added_num=1; int first=0; int key_type; size_t size_in_bit; if ( (!selected_key) || (!rsa) ) return -EINVAL; candidates=(peer_cap & hostinfo_get_ipmsg_crypt_capability()); g_assert(candidates); size_in_bit=RSA_size(rsa)*8; dbg_out("key size=%d.\n",size_in_bit); switch(size_in_bit){ case 512: dbg_out("This is 512 bit key.\n"); key_type=IPMSG_RSA_512; break; case 1024: dbg_out("This is 1024 bit key.\n"); key_type=IPMSG_RSA_1024; break; case 2048: dbg_out("This is 2048 bit key.\n"); key_type=IPMSG_RSA_2048; break; default: rc=-ENOENT; return rc; break; } if (!(key_type & candidates)) return -EINVAL; *selected_key=key_type; dbg_out("Selected key name in ipmsg:0x%x\n",key_type); return 0;}int select_signature(unsigned long peer_cap,unsigned long *selected_algo,int speed){ if (!selected_algo) return -EINVAL; if (!(peer_cap & SIGN_CAPS)) return -ENOENT; if (peer_cap & IPMSG_SIGN_MD5) *selected_algo=IPMSG_SIGN_MD5; if (peer_cap & IPMSG_SIGN_SHA1) *selected_algo=IPMSG_SIGN_SHA1; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -