00001
00026 #include "dh_tool.h"
00027
00028
00029 #ifdef ENABLE_SSL
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00043
00044
00045
00060 int save_DHspki_with_private(Buffer pki, FILE* fp, DH* dhkey)
00061 {
00062 unsigned int md;
00063 Buffer pv;
00064
00065 if (fp==NULL || dhkey==NULL) return FALSE;
00066
00067 md = JBXL_FIO_SPKI | JBXL_FIO_ORIGINAL;
00068 if (!save_tagged_Buffer(pki, fp, md, FALSE)) return FALSE;
00069
00070 pv = get_DHprivatekey(dhkey);
00071 if (pv.buf==NULL) return FALSE;
00072
00073 md = JBXL_FIO_PRIV_KEY | JBXL_FIO_ORIGINAL;
00074 if (!save_tagged_Buffer(pv, fp, md, FALSE)) return FALSE;
00075 free_Buffer(&pv);
00076
00077 return TRUE;
00078 }
00079
00080
00081
00091 Buffer read_DHspki_with_private(FILE* fp, DH** p_dhkey)
00092 {
00093 int n = 0, code;
00094 unsigned int md;
00095 Buffer pp, pv, pk, gk, yk;
00096
00097 pp = init_Buffer();
00098 if (fp==NULL) return pp;
00099
00100 md = JBXL_FIO_SPKI | JBXL_FIO_ORIGINAL;
00101 pp = read_tagged_Buffer(fp, &md);
00102 if (pp.buf==NULL) return pp;
00103
00104 if (*p_dhkey!=NULL) DH_free(*p_dhkey);
00105 *p_dhkey = DH_new();
00106 if (*p_dhkey==NULL) {
00107 free_Buffer(&pp);
00108 return pp;
00109 }
00110
00111 pk = get_DHPkey(pp);
00112 gk = get_DHGkey(pp);
00113 yk = get_DHYkey(pp);
00114
00115 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00116
00117 (*p_dhkey)->p = BN_bin2bn((const unsigned char*)(pk.buf), pk.vldsz, NULL);
00118 (*p_dhkey)->g = BN_bin2bn((const unsigned char*)(gk.buf), gk.vldsz, NULL);
00119 (*p_dhkey)->pub_key = BN_bin2bn((const unsigned char*)(yk.buf), yk.vldsz, NULL);
00120 #else
00121
00122 BIGNUM* dhp_bn = BN_bin2bn((const unsigned char*)(pk.buf), pk.vldsz, NULL);
00123 BIGNUM* dhg_bn = BN_bin2bn((const unsigned char*)(gk.buf), gk.vldsz, NULL);
00124 BIGNUM* dhy_bn = BN_bin2bn((const unsigned char*)(gk.buf), gk.vldsz, NULL);
00125
00126 if (dhp_bn!=NULL && dhg_bn!=NULL && dhy_bn!=NULL) {
00127 DH_set0_pqg(*p_dhkey, dhp_bn, NULL, dhg_bn);
00128 DH_set0_key(*p_dhkey, dhy_bn, NULL);
00129 }
00130 else {
00131 DH_free(*p_dhkey);
00132 *p_dhkey = NULL;
00133 }
00134 #endif
00135
00136 free_Buffer(&pk);
00137 free_Buffer(&gk);
00138 free_Buffer(&yk);
00139
00140
00141 if (*p_dhkey!=NULL) n = DH_check(*p_dhkey, &code);
00142 if (n!=1 || code!=0) {
00143 if (*p_dhkey!=NULL) DH_free(*p_dhkey);
00144 free_Buffer(&pp);
00145 return pp;
00146 }
00147
00148
00149 md = JBXL_FIO_PRIV_KEY | JBXL_FIO_ORIGINAL;
00150 pv = read_tagged_Buffer(fp, &md);
00151 if (pv.buf==NULL) {
00152 if (*p_dhkey!=NULL) DH_free(*p_dhkey);
00153 free_Buffer(&pp);
00154 return pp;
00155 }
00156
00157 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00158 (*p_dhkey)->priv_key = BN_bin2bn((const unsigned char*)(pv.buf), pv.vldsz, NULL);
00159 #else
00160 BIGNUM* priv_key = BN_bin2bn((const unsigned char*)(pv.buf), pv.vldsz, NULL);
00161 DH_set0_key(*p_dhkey, NULL, priv_key);
00162 #endif
00163
00164 free_Buffer(&pv);
00165
00166 return pp;
00167 }
00168
00169
00170
00191 Buffer get_DHspki_ff(char* filename, int ks, DH** p_dhkey)
00192 {
00193 Buffer pki;
00194 FILE* fp;
00195
00196 pki = init_Buffer();
00197 if (filename==NULL || p_dhkey==NULL) return pki;
00198
00199 if (file_exist(filename)) {
00200
00201 fp = fopen(filename, "rb");
00202 pki = read_DHspki_with_private(fp, p_dhkey);
00203 fclose(fp);
00204
00205 if (pki.buf!=NULL) {
00206 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00207 if (DH_size(*p_dhkey)<(ks+7)/8 || (*p_dhkey)->priv_key==NULL) free_Buffer(&pki);
00208 #else
00209 const BIGNUM* priv_key = DH_get0_priv_key(*p_dhkey);
00210 if (DH_size(*p_dhkey)<(ks+7)/8 || priv_key==NULL) free_Buffer(&pki);
00211 #endif
00212 }
00213 }
00214
00215 if (pki.buf==NULL) {
00216
00217 pki = gen_DHspki(ks, p_dhkey);
00218
00219
00220 fp = file_chmod_open(filename, (char*)"w", S_IRUSR | S_IWUSR);
00221 if (fp!=NULL) {
00222 save_DHspki_with_private(pki, fp, *p_dhkey);
00223 fclose(fp);
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232
00233 return pki;
00234 }
00235
00236
00237
00248 Buffer gen_DHspki(int ks, DH** p_dhkey)
00249 {
00250 int sz, n, code;
00251 Buffer px, pp, pk;
00252
00253 pk = init_Buffer();
00254 if (p_dhkey==NULL) return pk;
00255
00256
00257
00258 if (!RAND_load_file("/dev/urandom", 1024)) return pk;
00259
00260
00261 do {
00262 if (*p_dhkey!=NULL) DH_free(*p_dhkey);
00263 *p_dhkey = DH_new();
00264
00265 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00266 *p_dhkey = DH_generate_parameters(ks, DH_GENERATOR_2, NULL, NULL);
00267 #else
00268 n = DH_generate_parameters_ex(*p_dhkey, ks, DH_GENERATOR_2, NULL);
00269 #endif
00270 n = DH_check(*p_dhkey, &code);
00271 } while (n!=1 || code!=0);
00272
00273
00274 sz = DH_generate_key(*p_dhkey);
00275 if (sz==0) {
00276 DH_free(*p_dhkey);
00277 *p_dhkey = NULL;
00278 return pk;
00279 }
00280
00281
00282 sz = i2d_DHparams(*p_dhkey, NULL);
00283 pp = px = make_Buffer(sz);
00284 if (pp.buf==NULL) {
00285 DH_free(*p_dhkey);
00286 *p_dhkey = NULL;
00287 return pk;
00288 }
00289 pp.vldsz = i2d_DHparams(*p_dhkey, &(px.buf));
00290
00291
00292 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00293 sz = BN_num_bytes((*p_dhkey)->pub_key);
00294 #else
00295 const BIGNUM* pub_key = DH_get0_pub_key(*p_dhkey);
00296 sz = BN_num_bytes(pub_key);
00297 #endif
00298
00299 px = make_Buffer(sz);
00300 if (px.buf==NULL) {
00301 DH_free(*p_dhkey);
00302 *p_dhkey = NULL;
00303 free_Buffer(&pp);
00304 return pk;
00305 }
00306
00307 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00308 px.vldsz = BN_bn2bin((*p_dhkey)->pub_key, px.buf);
00309 #else
00310 px.vldsz = BN_bn2bin(pub_key, px.buf);
00311 #endif
00312
00313 pk = join_DHpubkey(pp, px);
00314
00315 free_Buffer(&pp);
00316 free_Buffer(&px);
00317
00318 return pk;
00319 }
00320
00321
00322
00335 Buffer gen_DHspki_fs(Buffer pki, DH** p_dhkey)
00336 {
00337 int sz, n = 0, code;
00338 Buffer px, pp, pk;
00339 Buffer pkey, gkey;
00340
00341
00342 pk = init_Buffer();
00343 if (p_dhkey==NULL) return pk;
00344
00345 if (*p_dhkey!=NULL) DH_free(*p_dhkey);
00346 *p_dhkey = DH_new();
00347 if (*p_dhkey==NULL) return pk;
00348
00349 pkey = get_DHPkey(pki);
00350 gkey = get_DHGkey(pki);
00351 if (pkey.buf==NULL || gkey.buf==NULL) {
00352 free_Buffer(&pkey);
00353 free_Buffer(&gkey);
00354 DH_free(*p_dhkey);
00355 *p_dhkey = NULL;
00356 return pk;
00357 }
00358
00359 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00360 (*p_dhkey)->p = BN_bin2bn((const unsigned char*)(pkey.buf), pkey.vldsz, NULL);
00361 (*p_dhkey)->g = BN_bin2bn((const unsigned char*)(gkey.buf), gkey.vldsz, NULL);
00362 #else
00363 BIGNUM* dhp_bn = BN_bin2bn((const unsigned char*)(pkey.buf), pkey.vldsz, NULL);
00364 BIGNUM* dhg_bn = BN_bin2bn((const unsigned char*)(gkey.buf), gkey.vldsz, NULL);
00365
00366 if (dhp_bn!=NULL && dhg_bn!=NULL) {
00367 DH_set0_pqg(*p_dhkey, dhp_bn, NULL, dhg_bn);
00368 }
00369 else {
00370 DH_free(*p_dhkey);
00371 *p_dhkey = NULL;
00372 }
00373
00374
00375 #endif
00376
00377 free_Buffer(&pkey);
00378 free_Buffer(&gkey);
00379
00380
00381 if (*p_dhkey!=NULL) n = DH_check(*p_dhkey, &code);
00382 if (n!=1 || code!=0) {
00383 if (*p_dhkey!=NULL) DH_free(*p_dhkey);
00384 *p_dhkey = NULL;
00385 return pk;
00386 }
00387
00388 sz = DH_generate_key(*p_dhkey);
00389 if (sz==0) {
00390 DH_free(*p_dhkey);
00391 *p_dhkey = NULL;
00392 return pk;
00393 }
00394
00395
00396 sz = i2d_DHparams(*p_dhkey, NULL);
00397 pp = px = make_Buffer(sz);
00398 if (pp.buf==NULL) {
00399 DH_free(*p_dhkey);
00400 *p_dhkey = NULL;
00401 return pk;
00402 }
00403 pp.vldsz = i2d_DHparams(*p_dhkey, &(px.buf));
00404
00405 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00406 sz = BN_num_bytes((*p_dhkey)->pub_key);
00407 #else
00408 const BIGNUM* pub_key = DH_get0_pub_key(*p_dhkey);
00409 sz = BN_num_bytes(pub_key);
00410 #endif
00411
00412 px = make_Buffer(sz);
00413 if (px.buf==NULL) {
00414 DH_free(*p_dhkey);
00415 *p_dhkey = NULL;
00416 free_Buffer(&pp);
00417 return px;
00418 }
00419
00420 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00421 px.vldsz = BN_bn2bin((*p_dhkey)->pub_key, px.buf);
00422 #else
00423 px.vldsz = BN_bn2bin(pub_key, px.buf);
00424 #endif
00425
00426 pk = join_DHpubkey(pp, px);
00427
00428 free_Buffer(&pp);
00429 free_Buffer(&px);
00430
00431 return pk;
00432 }
00433
00434
00435
00450 Buffer get_DHsharedkey(Buffer pki, DH* dhkey)
00451 {
00452 Buffer ykey, skey;
00453
00454 skey = init_Buffer();
00455 ykey = get_DHYkey(pki);
00456 if (ykey.buf==NULL) return skey;
00457
00458 skey = get_DHsharedkey_fY(ykey, dhkey);
00459
00460 free_Buffer(&ykey);
00461 return skey;
00462 }
00463
00464
00465
00480 Buffer get_DHsharedkey_fY(Buffer ykey, DH* dhkey)
00481 {
00482 int sz;
00483 Buffer buf;
00484
00485 buf = init_Buffer();
00486 if (dhkey==NULL) return buf;
00487
00488 BIGNUM* yk = BN_bin2bn((const unsigned char*)(ykey.buf), ykey.vldsz, NULL);
00489
00490 sz = DH_size(dhkey);
00491 buf = make_Buffer(sz);
00492 buf.vldsz = sz;
00493
00494 BN_free(yk);
00495 return buf;
00496 }
00497
00498
00499
00520 Buffer get_DHYkey(Buffer param)
00521 {
00522 int i, lp, sz=0;
00523 Buffer pp;
00524 pp = init_Buffer();
00525
00526 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00527 if (sz<0) return pp;
00528
00529 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00530 if (sz<0) return pp;
00531 sz = sz + lp;
00532
00533 sz = skip_DER_node(param, JBXL_ASN1_BIT, sz, &lp);
00534 if (sz<0) return pp;
00535 sz++;
00536
00537 sz = skip_DER_node(param, JBXL_ASN1_INT, sz, &lp);
00538 if (sz<0) return pp;
00539
00540 pp = make_Buffer(lp);
00541 if (pp.buf==NULL) return pp;
00542 for (i=0; i<lp; i++) pp.buf[i] = param.buf[sz+i];
00543 pp.vldsz = lp;
00544 return pp;
00545 }
00546
00547
00548
00569 Buffer get_DHPkey(Buffer param)
00570 {
00571 int i, lp, sz=0;
00572 Buffer pp;
00573 pp = init_Buffer();
00574
00575 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00576 if (sz<0) return pp;
00577
00578 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00579 if (sz<0) return pp;
00580
00581 sz = skip_DER_node(param, JBXL_ASN1_OBJ, sz, &lp);
00582 if (sz<0) return pp;
00583 sz = sz + lp;
00584
00585 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00586 if (sz<0) return pp;
00587
00588 sz = skip_DER_node(param, JBXL_ASN1_INT, sz, &lp);
00589 if (sz<0) return pp;
00590
00591 pp = make_Buffer(lp);
00592 if (pp.buf==NULL) return pp;
00593 for (i=0; i<lp; i++) pp.buf[i] = param.buf[sz+i];
00594 pp.vldsz = lp;
00595 return pp;
00596 }
00597
00598
00599
00621 Buffer get_DHGkey(Buffer param)
00622 {
00623 int i, lp, sz=0;
00624 Buffer pp;
00625 pp = init_Buffer();
00626
00627 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00628 if (sz<0) return pp;
00629
00630 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00631 if (sz<0) return pp;
00632
00633 sz = skip_DER_node(param, JBXL_ASN1_OBJ, sz, &lp);
00634 if (sz<0) return pp;
00635 sz = sz + lp;
00636
00637 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00638 if (sz<0) return pp;
00639
00640 sz = skip_DER_node(param, JBXL_ASN1_INT, sz, &lp);
00641 if (sz<0) return pp;
00642 sz = sz + lp;
00643
00644 sz = skip_DER_node(param, JBXL_ASN1_INT, sz, &lp);
00645 if (sz<0) return pp;
00646
00647 pp = make_Buffer(lp);
00648 if (pp.buf==NULL) return pp;
00649 for (i=0; i<lp; i++) pp.buf[i] = param.buf[sz+i];
00650 pp.vldsz = lp;
00651 return pp;
00652 }
00653
00654
00655
00676 Buffer get_DHalgorism(Buffer param)
00677 {
00678 int i, lp, sz=0;
00679 Buffer pp;
00680 pp = init_Buffer();
00681
00682 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00683 if (sz<0) return pp;
00684
00685 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
00686 if (sz<0) return pp;
00687
00688 sz = skip_DER_node(param, JBXL_ASN1_OBJ, sz, &lp);
00689 if (sz<0) return pp;
00690
00691 pp = make_Buffer(lp);
00692 if (pp.buf==NULL) return pp;
00693 for (i=0; i<lp; i++) pp.buf[i] = param.buf[sz+i];
00694 pp.vldsz = lp;
00695 return pp;
00696 }
00697
00698
00707 Buffer get_DHprivatekey(DH* dhkey)
00708 {
00709 int sz;
00710 Buffer pv;
00711
00712 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00713 sz = BN_num_bytes(dhkey->priv_key);
00714
00715 #else
00716 const BIGNUM* priv_key = DH_get0_pub_key(dhkey);
00717 sz = BN_num_bytes(priv_key);
00718 #endif
00719
00720 pv = make_Buffer(sz);
00721 if (pv.buf==NULL) return pv;
00722
00723 #if OPENSSL_VERSION_NUMBER < 0x10101000L
00724 pv.vldsz = BN_bn2bin(dhkey->priv_key, pv.buf);
00725
00726 #else
00727 pv.vldsz = BN_bn2bin(priv_key, pv.buf);
00728 #endif
00729
00730 return pv;
00731 }
00732
00733
00734
00767 Buffer join_DHpubkey(Buffer param, Buffer key)
00768 {
00769
00770 unsigned char dh_algor[]={0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x03,0x01};
00771
00772 int len_dh_algor = 11;
00773
00774 int ls, lp, la, sz;
00775 Buffer px, pp, pm;
00776
00777
00778 pp = init_Buffer();
00779 sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, 0, &lp);
00780 if (sz<0) return pp;
00781
00782 pp.buf = param.buf + sz;
00783 pp.bufsz = param.bufsz - sz;
00784 pp.vldsz = param.vldsz - sz;
00785
00786
00787 px = int2bin_DER(key.vldsz*8-1);
00788 pm = node2DER(px, JBXL_ASN1_INT);
00789 ls = pm.vldsz;
00790 free_Buffer(&px);
00791
00792
00793 px = make_Buffer(lp+ls);
00794 memcpy(px.buf, pp.buf, lp);
00795 memcpy(px.buf+lp, pm.buf, ls);
00796 px.vldsz = lp + ls;
00797 free_Buffer(&pm);
00798 pm = node2DER(px, JBXL_ASN1_SEQ_CNSTRCTD);
00799 ls = pm.vldsz;
00800 free_Buffer(&px);
00801
00802
00803 la = len_dh_algor;
00804 pp = make_Buffer(ls+la);
00805 memcpy(pp.buf, dh_algor, la);
00806 memcpy(pp.buf+la, pm.buf, ls);
00807 pp.vldsz = ls + la;
00808 free_Buffer(&pm);
00809 px = node2DER(pp, JBXL_ASN1_SEQ_CNSTRCTD);
00810 ls = px.vldsz;
00811 free_Buffer(&pp);
00812
00813
00814 pm = node2DER(key, JBXL_ASN1_INT);
00815 pp = node2DER(pm, JBXL_ASN1_BIT);
00816 lp = pp.vldsz;
00817 free_Buffer(&pm);
00818 pm = make_Buffer(ls+lp);
00819 memcpy(pm.buf, px.buf, ls);
00820 memcpy(pm.buf+ls, pp.buf, lp);
00821 pm.vldsz = ls + lp;
00822 free_Buffer(&px);
00823 free_Buffer(&pp);
00824
00825 pp = node2DER(pm, JBXL_ASN1_SEQ_CNSTRCTD);
00826 free_Buffer(&pm);
00827 return pp;
00828 }
00829
00830
00831 #endif