JunkBox_Lib  1.10.2
dh_tool.c
Go to the documentation of this file.
1 
25 #include "dh_tool.h"
26 
27 
28 #ifdef ENABLE_SSL
29 
30 /*
31 ###############################################################################################
32 for OpenSSL3
33 see https://stackoverflow.com/questions/71551116/openssl-3-diffie-hellman-key-exchange-c
34 see https://github.com/eugen15/diffie-hellman-cpp
35 ###############################################################################################
36 */
37 
38 
39 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
40 
42 // Diffie-Hellman 鍵交換法
43 // OpenSSL v3.x
44 //
45 
55 EVP_PKEY* JBXL_DH_new(OSSL_PARAM* params, int mode)
56 {
57  EVP_PKEY *dhkey = NULL;
58  EVP_PKEY *param_key = NULL;
59 
60  EVP_PKEY_CTX* ctx = NULL;
61 
62  if (params!=NULL && mode>0) { // params!=NULL, mode>0
63  ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL);
64  if (!ctx) return NULL;
65 
66  if (EVP_PKEY_fromdata_init(ctx) <= 0) {
67  EVP_PKEY_CTX_free(ctx);
68  return NULL;
69  }
70 
71  if (EVP_PKEY_fromdata(ctx, &dhkey, EVP_PKEY_KEYPAIR, params) <= 0) {
72  dhkey = NULL;
73  }
74  }
75 
76  else {
77  ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
78  if (!ctx) return NULL;
79 
80  if (EVP_PKEY_paramgen_init(ctx) <= 0) {
81  EVP_PKEY_CTX_free(ctx);
82  return NULL;
83  }
84 
85  if (params==NULL) { // params==NULL, mode==0/512/1024/2048
86  if (mode!=512 && mode!=1024) mode = 2048;
87  if (EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, mode) <= 0) {
88  EVP_PKEY_CTX_free(ctx);
89  return NULL;
90  }
91  }
92  else { // params!=NULL, mode==0
93  if (EVP_PKEY_CTX_set_params(ctx, params) <= 0) {
94  EVP_PKEY_CTX_free(ctx);
95  return NULL;
96  }
97  }
98 
99  if (EVP_PKEY_paramgen(ctx, &param_key) <= 0) {
100  EVP_PKEY_CTX_free(ctx);
101  return NULL;
102  }
103  EVP_PKEY_CTX_free(ctx);
104 
105  EVP_PKEY_CTX *key_ctx = EVP_PKEY_CTX_new(param_key, NULL);
106  if (!key_ctx) {
107  EVP_PKEY_free(param_key);
108  return NULL;
109  }
110 
111  if (EVP_PKEY_keygen_init(key_ctx) <= 0 || EVP_PKEY_keygen(key_ctx, &dhkey) <= 0) {
112  dhkey = NULL;
113  }
114 
115  EVP_PKEY_CTX_free(key_ctx);
116  EVP_PKEY_free(param_key);
117  }
118 
119  return dhkey;
120 }
121 
122 
135 Buffer gen_DHspki(int ks, EVP_PKEY** p_dhkey)
136 {
137  int sz;
138  Buffer pk;
139 
140  pk = init_Buffer();
141  if (p_dhkey==NULL) return pk;
142  if (*p_dhkey!=NULL) EVP_PKEY_free(*p_dhkey);
143  if (ks<=0) ks = 2048;
144 
145  //DEBUG_MODE PRINT_MESG("Load /dev/urandom.\n");
146  //if (!RAND_load_file("/dev/urandom", 1024)) return pk;
147 
148  //DEBUG_MODE PRINT_MESG("Generate parameters.\n");
149  *p_dhkey = JBXL_DH_new(NULL, ks);
150  if (*p_dhkey==NULL) {
151  return pk;
152  }
153 
154  //DEBUG_MODE PRINT_MESG("Check key size.\n");
155  sz = i2d_PUBKEY(*p_dhkey, NULL);
156  if (sz<=0) {
157  EVP_PKEY_free(*p_dhkey);
158  *p_dhkey = NULL;
159  return pk;
160  }
161  pk = make_Buffer(sz); // パラメタを入れるメモリを確保
162 
163  unsigned char *p = pk.buf;
164  pk.vldsz = i2d_PUBKEY(*p_dhkey, &p);
165 
166  return pk;
167 }
168 
169 
182 Buffer gen_DHspki_fs(Buffer pki, EVP_PKEY** p_dhkey)
183 {
184  Buffer pk;
185  Buffer pkey, gkey;
186 
187  //
188  pk = init_Buffer();
189  if (p_dhkey==NULL) return pk;
190  if (*p_dhkey != NULL) EVP_PKEY_free(*p_dhkey);
191 
192  pkey = get_DHPkey(pki);
193  gkey = get_DHGkey(pki);
194  if (pkey.buf==NULL || gkey.buf==NULL) {
195  free_Buffer(&pkey);
196  free_Buffer(&gkey);
197  JBXL_DH_free(*p_dhkey);
198  *p_dhkey = NULL;
199  return pk;
200  }
201 
202  BIGNUM* dhp_bn = BN_bin2bn((const unsigned char*)(pkey.buf), pkey.vldsz, NULL);
203  BIGNUM* dhg_bn = BN_bin2bn((const unsigned char*)(gkey.buf), gkey.vldsz, NULL);
204  //
205  if (dhp_bn==NULL || dhg_bn==NULL) {
206  free_Buffer(&pkey);
207  free_Buffer(&gkey);
208  if (dhp_bn!=NULL) BN_free(dhp_bn);
209  if (dhg_bn!=NULL) BN_free(dhg_bn);
210  return pk;
211  }
212 
213  OSSL_PARAM params[] = {
214  OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, dhp_bn, BN_num_bytes(dhp_bn)),
215  OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, dhg_bn, BN_num_bytes(dhg_bn)),
216  OSSL_PARAM_END
217  };
218  *p_dhkey = JBXL_DH_new(params, 1);
219 
220  free_Buffer(&pkey);
221  free_Buffer(&gkey);
222  BN_free(dhp_bn);
223  BN_free(dhg_bn);
224  //
225 
226  int sz = i2d_PUBKEY(*p_dhkey, NULL);
227  pk = make_Buffer(sz); // パラメタを入れるメモリを確保
228  if (pk.buf==NULL) {
229  JBXL_DH_free(*p_dhkey);
230  *p_dhkey = NULL;
231  return pk;
232  }
233  unsigned char* p = pk.buf;
234  pk.vldsz = i2d_PUBKEY(*p_dhkey, &p);
235 
236  return pk;
237 }
238 
239 
249 Buffer read_DHspki_with_private(FILE* fp, EVP_PKEY** p_dhkey)
250 {
251  unsigned int md;
252  Buffer pp, pv, pk, gk, yk;
253 
254  pp = init_Buffer();
255  if (fp==NULL) return pp;
256  if (*p_dhkey!=NULL) JBXL_DH_free(*p_dhkey);
257 
259  pp = read_tagged_Buffer(fp, &md);
260  if (pp.buf==NULL) return pp;
261 
262  pk = get_DHPkey(pp);
263  gk = get_DHGkey(pp);
264  yk = get_DHYkey(pp);
265 
266  BIGNUM* dhp_bn = BN_bin2bn((const unsigned char*)(pk.buf), pk.vldsz, NULL);
267  BIGNUM* dhg_bn = BN_bin2bn((const unsigned char*)(gk.buf), gk.vldsz, NULL);
268  BIGNUM* dhy_bn = BN_bin2bn((const unsigned char*)(yk.buf), yk.vldsz, NULL);
269 
270  // Private KEY の読み込み
272  pv = read_tagged_Buffer(fp, &md);
273  if (pv.buf==NULL) {
274  free_Buffer(&pk);
275  free_Buffer(&gk);
276  free_Buffer(&yk);
277  if (*p_dhkey!=NULL) JBXL_DH_free(*p_dhkey);
278  free_Buffer(&pp);
279  return pp;
280  }
281  BIGNUM* prv_bn = BN_bin2bn((const unsigned char*)(pv.buf), pv.vldsz, NULL);
282  free_Buffer(&pv);
283 
284  OSSL_PARAM params[] = {
285  OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, dhp_bn, BN_num_bytes(dhp_bn)),
286  OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, dhg_bn, BN_num_bytes(dhg_bn)),
287  OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, dhy_bn, BN_num_bytes(dhy_bn)),
288  OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, prv_bn, BN_num_bytes(prv_bn)),
289  OSSL_PARAM_END
290  };
291  *p_dhkey = JBXL_DH_new(params, 1);
292 
293  free_Buffer(&pk);
294  free_Buffer(&gk);
295  free_Buffer(&yk);
296 
297  if (dhp_bn!=NULL) BN_free(dhp_bn);
298  if (dhg_bn!=NULL) BN_free(dhg_bn);
299  if (dhy_bn!=NULL) BN_free(dhy_bn);
300  if (prv_bn!=NULL) BN_free(prv_bn);
301 
302  return pp;
303 }
304 
305 
314 Buffer get_DHprivatekey(EVP_PKEY* dhkey)
315 {
316  Buffer pv = init_Buffer();
317  BIGNUM* priv_key = NULL;
318 
319  if (dhkey == NULL) return pv;
320 
321  if (EVP_PKEY_get_bn_param(dhkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv_key) <= 0 || priv_key == NULL) {
322  return pv;
323  }
324 
325  int sz = BN_num_bytes(priv_key);
326  pv = make_Buffer(sz);
327  if (pv.buf != NULL) {
328  pv.vldsz = BN_bn2bin(priv_key, pv.buf);
329  }
330 
331  BN_free(priv_key);
332  return pv;
333 }
334 
335 
350 Buffer get_DHsharedkey_fY(Buffer ykey, JBXL_DH* dhkey)
351 {
352  Buffer buf = init_Buffer();
353  if (dhkey == NULL || ykey.buf == NULL || ykey.vldsz <= 0) return buf;
354 
355  EVP_PKEY_CTX* ctx = NULL;
356  EVP_PKEY* peerkey = NULL;
357  BIGNUM* dhy_bn = NULL;
358 
359  // 相手の Y鍵から EVP_PKEY を作成
360  dhy_bn = BN_bin2bn((const unsigned char*)ykey.buf, ykey.vldsz, NULL);
361  if (dhy_bn == NULL) return buf;
362 
363  BIGNUM* dhp_bn = NULL;
364  BIGNUM* dhg_bn = NULL;
365 
366  EVP_PKEY_get_bn_param(dhkey, OSSL_PKEY_PARAM_FFC_P, &dhp_bn);
367  EVP_PKEY_get_bn_param(dhkey, OSSL_PKEY_PARAM_FFC_G, &dhg_bn);
368 
369  if (dhp_bn==NULL || dhg_bn==NULL) {
370  if (dhp_bn!=NULL) BN_free(dhp_bn);
371  if (dhg_bn!=NULL) BN_free(dhg_bn);
372  BN_free(dhy_bn);
373  return buf;
374  }
375 
376  OSSL_PARAM peer_params[] = {
377  OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, dhp_bn, BN_num_bytes(dhp_bn)),
378  OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, dhg_bn, BN_num_bytes(dhg_bn)),
379  OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, dhy_bn, BN_num_bytes(dhy_bn)),
380  OSSL_PARAM_END
381  };
382  peerkey = JBXL_DH_new(peer_params, 1);
383 
384  BN_free(dhp_bn);
385  BN_free(dhg_bn);
386 
387  if (peerkey == NULL) {
388  BN_free(dhy_bn);
389  return buf;
390  }
391 
392  ctx = EVP_PKEY_CTX_new(dhkey, NULL);
393  if (ctx == NULL) {
394  EVP_PKEY_free(peerkey);
395  return buf;
396  }
397 
398  if (EVP_PKEY_derive_init(ctx) <= 0 || EVP_PKEY_derive_set_peer(ctx, peerkey) <= 0) {
399  EVP_PKEY_CTX_free(ctx);
400  EVP_PKEY_free(peerkey);
401  return buf;
402  }
403 
404  size_t sz = 0;
405  if (EVP_PKEY_derive(ctx, NULL, &sz) <= 0) {
406  EVP_PKEY_CTX_free(ctx);
407  EVP_PKEY_free(peerkey);
408  return buf;
409  }
410 
411  buf = make_Buffer((int)sz);
412  if (buf.buf == NULL) {
413  EVP_PKEY_CTX_free(ctx);
414  EVP_PKEY_free(peerkey);
415  return buf;
416  }
417 
418  if (EVP_PKEY_derive(ctx, buf.buf, &sz) <= 0) {
419  free_Buffer(&buf);
420  buf = init_Buffer();
421  }
422  else {
423  buf.vldsz = (int)sz;
424  }
425 
426  EVP_PKEY_CTX_free(ctx);
427  EVP_PKEY_free(peerkey);
428  BN_free(dhy_bn);
429 
430  return buf;
431 }
432 
433 
434 #else
435 
436 
438 // Diffie-Hellman 鍵交換法
439 // OpenSSL v1.x
440 //
441 
452 Buffer gen_DHspki(int ks, JBXL_DH** p_dhkey)
453 {
454  int sz, n, code;
455  Buffer px, pp, pk;
456 
457  pk = init_Buffer();
458  if (p_dhkey==NULL) return pk;
459  if (ks<=0) ks = 2048;
460 
461  //if (!RAND_load_file("/dev/random", 1024)) return pk;
462  //DEBUG_MODE PRINT_MESG("Load /dev/urandom.\n");
463  if (!RAND_load_file("/dev/urandom", 1024)) return pk;
464 
465  //DEBUG_MODE PRINT_MESG("Generate parameters.\n");
466  do {
467  if (*p_dhkey!=NULL) JBXL_DH_free(*p_dhkey);
468  *p_dhkey = DH_new();
469 
470 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
471  n = DH_generate_parameters_ex(*p_dhkey, ks, DH_GENERATOR_2, NULL);
472 #else
473  *p_dhkey = DH_generate_parameters(ks, DH_GENERATOR_2, NULL, NULL);
474 #endif
475  n = DH_check(*p_dhkey, &code);
476  } while (n!=1 || code!=0);
477 
478  //DEBUG_MODE PRINT_MESG("Generate key.\n");
479  sz = DH_generate_key(*p_dhkey); // 公開鍵(DH->pub_key)と秘密鍵(DH->priv_key)の生成
480  if (sz==0) {
481  JBXL_DH_free(*p_dhkey);
482  *p_dhkey = NULL;
483  return pk;
484  }
485 
486  //DEBUG_MODE PRINT_MESG("Check key size.\n");
487  sz = i2d_DHparams(*p_dhkey, NULL); // パラメタのサイズを検査
488  pp = px = make_Buffer(sz); // パラメタを入れるメモリを確保
489  if (pp.buf==NULL) {
490  JBXL_DH_free(*p_dhkey);
491  *p_dhkey = NULL;
492  return pk;
493  }
494  pp.vldsz = i2d_DHparams(*p_dhkey, &(px.buf)); // パラメタ(P,G鍵)を DER形式へ.pp.bufに格納.
495  // px.bufは破壊される.
496 
497 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
498  const BIGNUM* pub_key = DH_get0_pub_key(*p_dhkey);
499  sz = BN_num_bytes(pub_key);
500 #else
501  sz = BN_num_bytes((*p_dhkey)->pub_key);
502 #endif
503 
504  px = make_Buffer(sz);
505  if (px.buf==NULL) {
506  JBXL_DH_free(*p_dhkey);
507  *p_dhkey = NULL;
508  free_Buffer(&pp);
509  return pk;
510  }
511 
512 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
513  px.vldsz = BN_bn2bin(pub_key, px.buf);
514 #else
515  px.vldsz = BN_bn2bin((*p_dhkey)->pub_key, px.buf);
516 #endif
517 
518  pk = join_DHpubkey(pp, px); // pp -> DHパラメタ(P,G鍵), px-> Y鍵
519 
520  free_Buffer(&pp);
521  free_Buffer(&px);
522 
523  return pk;
524 }
525 
526 
539 Buffer gen_DHspki_fs(Buffer pki, JBXL_DH** p_dhkey)
540 {
541  int sz, n = 0, code;
542  Buffer px, pp, pk;
543  Buffer pkey, gkey;
544 
545  //
546  pk = init_Buffer();
547  if (p_dhkey==NULL) return pk;
548  //
549  if (*p_dhkey!=NULL) JBXL_DH_free(*p_dhkey);
550  *p_dhkey = DH_new();
551  if (*p_dhkey==NULL) return pk;
552 
553  pkey = get_DHPkey(pki);
554  gkey = get_DHGkey(pki);
555  if (pkey.buf==NULL || gkey.buf==NULL) {
556  free_Buffer(&pkey);
557  free_Buffer(&gkey);
558  JBXL_DH_free(*p_dhkey);
559  *p_dhkey = NULL;
560  return pk;
561  }
562 
563 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
564  BIGNUM* dhp_bn = BN_bin2bn((const unsigned char*)(pkey.buf), pkey.vldsz, NULL);
565  BIGNUM* dhg_bn = BN_bin2bn((const unsigned char*)(gkey.buf), gkey.vldsz, NULL);
566  //
567  if (dhp_bn!=NULL && dhg_bn!=NULL) {
568  DH_set0_pqg(*p_dhkey, dhp_bn, NULL, dhg_bn);
569  }
570  else {
571  JBXL_DH_free(*p_dhkey);
572  *p_dhkey = NULL;
573  }
574  //BN_free(dhp_bn); // DHkeyの中身も消えてしまうので ここでは freeしない
575  //BN_free(dhg_bn);
576 #else
577  (*p_dhkey)->p = BN_bin2bn((const unsigned char*)(pkey.buf), pkey.vldsz, NULL);
578  (*p_dhkey)->g = BN_bin2bn((const unsigned char*)(gkey.buf), gkey.vldsz, NULL);
579 #endif
580 
581  free_Buffer(&pkey);
582  free_Buffer(&gkey);
583 
584  //
585  if (*p_dhkey!=NULL) n = DH_check(*p_dhkey, &code);
586  if (n!=1 || code!=0) {
587  if (*p_dhkey!=NULL) JBXL_DH_free(*p_dhkey);
588  *p_dhkey = NULL;
589  return pk;
590  }
591 
592  sz = DH_generate_key(*p_dhkey);
593  if (sz==0) {
594  JBXL_DH_free(*p_dhkey);
595  *p_dhkey = NULL;
596  return pk;
597  }
598 
599  //
600  sz = i2d_DHparams(*p_dhkey, NULL); // パラメタのサイズを検査
601  pp = px = make_Buffer(sz); // パラメタを入れるメモリを確保
602  if (pp.buf==NULL) {
603  JBXL_DH_free(*p_dhkey);
604  *p_dhkey = NULL;
605  return pk;
606  }
607  pp.vldsz = i2d_DHparams(*p_dhkey, &(px.buf)); // パラメタ(P,G鍵)を DER形式へ.pp.bufに格納.
608  // px.bufは破壊される.
609 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
610  const BIGNUM* pub_key = DH_get0_pub_key(*p_dhkey);
611  sz = BN_num_bytes(pub_key);
612 #else
613  sz = BN_num_bytes((*p_dhkey)->pub_key);
614 #endif
615 
616  px = make_Buffer(sz);
617  if (px.buf==NULL) {
618  JBXL_DH_free(*p_dhkey);
619  *p_dhkey = NULL;
620  free_Buffer(&pp);
621  return px;
622  }
623 
624 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
625  px.vldsz = BN_bn2bin(pub_key, px.buf); // 公開鍵(Y鍵)の DER形式
626 #else
627  px.vldsz = BN_bn2bin((*p_dhkey)->pub_key, px.buf); // 公開鍵(Y鍵)の DER形式
628 #endif
629 
630  pk = join_DHpubkey(pp, px); // pp -> DHパラメタ(P,G鍵), px-> Y鍵
631 
632  free_Buffer(&pp);
633  free_Buffer(&px);
634 
635  return pk;
636 }
637 
638 
648 Buffer read_DHspki_with_private(FILE* fp, JBXL_DH** p_dhkey)
649 {
650  int n = 0, code;
651  unsigned int md;
652  Buffer pp, pv, pk, gk, yk;
653 
654  pp = init_Buffer();
655  if (fp==NULL) return pp;
656 
658  pp = read_tagged_Buffer(fp, &md);
659  if (pp.buf==NULL) return pp;
660 
661  if (*p_dhkey!=NULL) JBXL_DH_free(*p_dhkey);
662  *p_dhkey = DH_new();
663  if (*p_dhkey==NULL) {
664  free_Buffer(&pp);
665  return pp;
666  }
667 
668  pk = get_DHPkey(pp);
669  gk = get_DHGkey(pp);
670  yk = get_DHYkey(pp);
671 
672 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
673  // v1.1.1
674  BIGNUM* dhp_bn = BN_bin2bn((const unsigned char*)(pk.buf), pk.vldsz, NULL);
675  BIGNUM* dhg_bn = BN_bin2bn((const unsigned char*)(gk.buf), gk.vldsz, NULL);
676  BIGNUM* dhy_bn = BN_bin2bn((const unsigned char*)(yk.buf), yk.vldsz, NULL);
677 
678  if (dhp_bn!=NULL && dhg_bn!=NULL && dhy_bn!=NULL) {
679  DH_set0_pqg(*p_dhkey, dhp_bn, NULL, dhg_bn);
680  DH_set0_key(*p_dhkey, dhy_bn, NULL);
681  }
682  else {
683  JBXL_DH_free(*p_dhkey);
684  *p_dhkey = NULL;
685  }
686 #else
687  // v1.1.0
688  (*p_dhkey)->p = BN_bin2bn((const unsigned char*)(pk.buf), pk.vldsz, NULL);
689  (*p_dhkey)->g = BN_bin2bn((const unsigned char*)(gk.buf), gk.vldsz, NULL);
690  (*p_dhkey)->pub_key = BN_bin2bn((const unsigned char*)(yk.buf), yk.vldsz, NULL);
691 #endif
692 
693  free_Buffer(&pk);
694  free_Buffer(&gk);
695  free_Buffer(&yk);
696 
697  // 鍵のチェック
698  if (*p_dhkey!=NULL) n = DH_check(*p_dhkey, &code);
699  if (n!=1 || code!=0) {
700  if (*p_dhkey!=NULL) JBXL_DH_free(*p_dhkey);
701  free_Buffer(&pp);
702  return pp;
703  }
704 
705  // Private KEY の読み込み
707  pv = read_tagged_Buffer(fp, &md);
708  if (pv.buf==NULL) {
709  if (*p_dhkey!=NULL) JBXL_DH_free(*p_dhkey);
710  free_Buffer(&pp);
711  return pp;
712  }
713 
714 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
715  BIGNUM* priv_key = BN_bin2bn((const unsigned char*)(pv.buf), pv.vldsz, NULL);
716  DH_set0_key(*p_dhkey, NULL, priv_key);
717 #else
718  (*p_dhkey)->priv_key = BN_bin2bn((const unsigned char*)(pv.buf), pv.vldsz, NULL);
719 #endif
720 
721  free_Buffer(&pv);
722 
723  return pp;
724 }
725 
726 
735 Buffer get_DHprivatekey(JBXL_DH* dhkey)
736 {
737  int sz;
738  Buffer pv;
739 
740 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
741  const BIGNUM* priv_key = DH_get0_priv_key(dhkey);
742  sz = BN_num_bytes(priv_key);
743 #else
744  sz = BN_num_bytes(dhkey->priv_key);
745 #endif
746 
747  pv = make_Buffer(sz);
748  if (pv.buf==NULL) return pv;
749 
750 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
751  pv.vldsz = BN_bn2bin(priv_key, pv.buf);
752 #else
753  pv.vldsz = BN_bn2bin(dhkey->priv_key, pv.buf);
754 #endif
755 
756  return pv;
757 }
758 
759 
772 Buffer get_DHsharedkey_fY(Buffer ykey, JBXL_DH* dhkey)
773 {
774  int sz;
775  Buffer buf;
776 
777  buf = init_Buffer();
778  if (dhkey == NULL || ykey.buf == NULL || ykey.vldsz <= 0) return buf;
779 
780  // 相手の公開鍵 Y を BIGNUM に変換
781  BIGNUM* yk = BN_bin2bn((const unsigned char*)(ykey.buf), ykey.vldsz, NULL);
782  if (yk == NULL) return buf;
783 
784  // 共通鍵のサイズを確保(DH_size は出力バイト数)
785  sz = JBXL_DH_size(dhkey);
786  buf = make_Buffer(sz);
787  if (buf.buf == NULL) {
788  BN_free(yk);
789  return init_Buffer();
790  }
791 
792  // 共通鍵を計算
793  buf.vldsz = DH_compute_key(buf.buf, yk, dhkey);
794 
795  BN_free(yk);
796 
797  // エラー時は解放して空のバッファを返す
798  if (buf.vldsz <= 0) {
799  free_Buffer(&buf);
800  return init_Buffer();
801  }
802 
803  return buf;
804 }
805 
806 
807 #endif
808 
809 
811 // Diffie-Hellman 鍵交換法
812 // 共通部分
813 //
814 
835 Buffer get_DHspki_ff(char* filename, int ks, JBXL_DH** p_dhkey)
836 {
837  Buffer pki;
838  FILE* fp;
839 
840  pki = init_Buffer();
841  if (filename==NULL || p_dhkey==NULL) return pki;
842 
843  if (file_exist(filename)) {
844  //DEBUG_MODE PRINT_MESG("Load DH public key. ");
845  fp = fopen(filename, "rb");
846  pki = read_DHspki_with_private(fp, p_dhkey);
847  fclose(fp);
848  //DEBUG_MODE PRINT_MESG("... done.\n");
849  if (pki.buf!=NULL) {
850 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
851  // NOP No Check
852 #elif OPENSSL_VERSION_NUMBER >= 0x10101000L
853  const BIGNUM* priv_key = DH_get0_priv_key(*p_dhkey);
854  if (DH_size(*p_dhkey)<(ks+7)/8 || priv_key==NULL) free_Buffer(&pki); // v1.1.0
855 #else
856  if (DH_size(*p_dhkey)<(ks+7)/8 || (*p_dhkey)->priv_key==NULL) free_Buffer(&pki); // v1.1.0
857 #endif
858  }
859  }
860 
861  if (pki.buf==NULL) {
862  //DEBUG_MODE PRINT_MESG("Generate DH public key.");
863  pki = gen_DHspki(ks, p_dhkey);
864  //DEBUG_MODE PRINT_MESG("... done.\n");
865 
866  fp = file_chmod_open(filename, (char*)"w", S_IRUSR | S_IWUSR);
867  if (fp!=NULL) {
868  save_DHspki_with_private(pki, fp, *p_dhkey);
869  fclose(fp);
870  }
871  }
872 
873  //DEBUG_MODE {
874  // Buffer enc;
875  // enc = encode_base64_Buffer(pki);
876  // DEBUG_MESG("SPKI = [%s]\n", enc.buf);
877  // free_Buffer(&enc);
878  //}
879  return pki;
880 }
881 
882 
897 int save_DHspki_with_private(Buffer pki, FILE* fp, JBXL_DH* dhkey)
898 {
899  unsigned int md;
900  Buffer pv;
901 
902  if (fp==NULL || dhkey==NULL) return FALSE;
903 
905  if (!save_tagged_Buffer(pki, fp, md, FALSE)) return FALSE;
906 
907  pv = get_DHprivatekey(dhkey);
908  if (pv.buf==NULL) return FALSE;
909 
911  if (!save_tagged_Buffer(pv, fp, md, FALSE)) return FALSE;
912  free_Buffer(&pv);
913 
914  return TRUE;
915 }
916 
917 
932 Buffer get_DHsharedkey(Buffer pki, JBXL_DH* dhkey)
933 {
934  Buffer ykey, skey;
935 
936  skey = init_Buffer();
937  ykey = get_DHYkey(pki);
938  if (ykey.buf==NULL) return skey;
939 
940  skey = get_DHsharedkey_fY(ykey, dhkey);
941 
942  free_Buffer(&ykey);
943  return skey;
944 }
945 
946 
967 Buffer get_DHYkey(Buffer param)
968 {
969  int i, lp, sz=0;
970  Buffer pp;
971  pp = init_Buffer();
972 
973  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
974  if (sz<0) return pp;
975 
976  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
977  if (sz<0) return pp;
978  sz = sz + lp;
979 
980  sz = skip_DER_node(param, JBXL_ASN1_BIT, sz, &lp);
981  if (sz<0) return pp;
982  sz++; // for Seed(0x00)
983 
984  sz = skip_DER_node(param, JBXL_ASN1_INT, sz, &lp);
985  if (sz<0) return pp;
986 
987  pp = make_Buffer(lp);
988  if (pp.buf==NULL) return pp;
989  for (i=0; i<lp; i++) pp.buf[i] = param.buf[sz+i];
990  pp.vldsz = lp;
991  return pp;
992 }
993 
994 
1015 Buffer get_DHPkey(Buffer param)
1016 {
1017  int i, lp, sz=0;
1018  Buffer pp;
1019  pp = init_Buffer();
1020 
1021  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
1022  if (sz<0) return pp;
1023 
1024  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
1025  if (sz<0) return pp;
1026 
1027  sz = skip_DER_node(param, JBXL_ASN1_OBJ, sz, &lp);
1028  if (sz<0) return pp;
1029  sz = sz + lp;
1030 
1031  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
1032  if (sz<0) return pp;
1033 
1034  sz = skip_DER_node(param, JBXL_ASN1_INT, sz, &lp);
1035  if (sz<0) return pp;
1036 
1037  pp = make_Buffer(lp);
1038  if (pp.buf==NULL) return pp;
1039  for (i=0; i<lp; i++) pp.buf[i] = param.buf[sz+i];
1040  pp.vldsz = lp;
1041  return pp;
1042 }
1043 
1044 
1066 Buffer get_DHGkey(Buffer param)
1067 {
1068  int i, lp, sz=0;
1069  Buffer pp;
1070  pp = init_Buffer();
1071 
1072  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
1073  if (sz<0) return pp;
1074 
1075  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
1076  if (sz<0) return pp;
1077 
1078  sz = skip_DER_node(param, JBXL_ASN1_OBJ, sz, &lp);
1079  if (sz<0) return pp;
1080  sz = sz + lp;
1081 
1082  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
1083  if (sz<0) return pp;
1084 
1085  sz = skip_DER_node(param, JBXL_ASN1_INT, sz, &lp);
1086  if (sz<0) return pp;
1087  sz = sz + lp;
1088 
1089  sz = skip_DER_node(param, JBXL_ASN1_INT, sz, &lp);
1090  if (sz<0) return pp;
1091 
1092  pp = make_Buffer(lp);
1093  if (pp.buf==NULL) return pp;
1094  for (i=0; i<lp; i++) pp.buf[i] = param.buf[sz+i];
1095  pp.vldsz = lp;
1096  return pp;
1097 }
1098 
1099 
1120 Buffer get_DHalgorism(Buffer param)
1121 {
1122  int i, lp, sz=0;
1123  Buffer pp;
1124  pp = init_Buffer();
1125 
1126  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
1127  if (sz<0) return pp;
1128 
1129  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, sz, &lp);
1130  if (sz<0) return pp;
1131 
1132  sz = skip_DER_node(param, JBXL_ASN1_OBJ, sz, &lp);
1133  if (sz<0) return pp;
1134 
1135  pp = make_Buffer(lp);
1136  if (pp.buf==NULL) return pp;
1137  for (i=0; i<lp; i++) pp.buf[i] = param.buf[sz+i];
1138  pp.vldsz = lp;
1139  return pp;
1140 }
1141 
1142 
1175 Buffer join_DHpubkey(Buffer param, Buffer key)
1176 {
1177 // unsigned char dh_algor[]={0x06,0x07,0x2a,0x86,0x48,0xce,0x3e,0x02,0x01}; // DH ?
1178  unsigned char dh_algor[]={0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x03,0x01}; // RSA ?
1179  // ↑ RSAアルゴリズム?
1180  int len_dh_algor = 11;
1181 
1182  int ls, lp, la, sz;
1183  Buffer px, pp, pm;
1184 
1185  // [P鍵 + G鍵] → pp
1186  pp = init_Buffer();
1187  sz = skip_DER_node(param, JBXL_ASN1_SEQ_CNSTRCTD, 0, &lp);
1188  if (sz<0) return pp;
1189 
1190  pp.buf = param.buf + sz;
1191  pp.bufsz = param.bufsz - sz;
1192  pp.vldsz = param.vldsz - sz;
1193 
1194  // [鍵サイズ] → pm
1195  px = int2bin_DER(key.vldsz*8-1);
1196  pm = node2DER(px, JBXL_ASN1_INT);
1197  ls = pm.vldsz;
1198  free_Buffer(&px);
1199 
1200  // pp[P鍵 + G鍵] + pm[鍵サイズ] → pm
1201  px = make_Buffer(lp+ls);
1202  memcpy(px.buf, pp.buf, lp);
1203  memcpy(px.buf+lp, pm.buf, ls);
1204  px.vldsz = lp + ls;
1205  free_Buffer(&pm); // ppを freeしてはいけない
1206  pm = node2DER(px, JBXL_ASN1_SEQ_CNSTRCTD);
1207  ls = pm.vldsz;
1208  free_Buffer(&px);
1209 
1210  // dh_algor[アルゴリズム] + pm[P鍵 + G鍵 + 鍵サイズ] → px
1211  la = len_dh_algor;
1212  pp = make_Buffer(ls+la);
1213  memcpy(pp.buf, dh_algor, la);
1214  memcpy(pp.buf+la, pm.buf, ls);
1215  pp.vldsz = ls + la;
1216  free_Buffer(&pm);
1217  px = node2DER(pp, JBXL_ASN1_SEQ_CNSTRCTD);
1218  ls = px.vldsz;
1219  free_Buffer(&pp);
1220 
1221  // px[アルゴリズム + P鍵 + G鍵 + 鍵サイズ] + pp[Y鍵] → pm
1222  pm = node2DER(key, JBXL_ASN1_INT);
1223  pp = node2DER(pm, JBXL_ASN1_BIT);
1224  lp = pp.vldsz;
1225  free_Buffer(&pm);
1226  pm = make_Buffer(ls+lp);
1227  memcpy(pm.buf, px.buf, ls);
1228  memcpy(pm.buf+ls, pp.buf, lp);
1229  pm.vldsz = ls + lp;
1230  free_Buffer(&px);
1231  free_Buffer(&pp);
1232 
1233  pp = node2DER(pm, JBXL_ASN1_SEQ_CNSTRCTD);
1234  free_Buffer(&pm);
1235  return pp;
1236 }
1237 
1238 #endif
#define JBXL_ASN1_BIT
BIT_STRING.
Definition: asn1_node.h:24
#define JBXL_ASN1_INT
INTEGER.
Definition: asn1_node.h:23
#define JBXL_ASN1_OBJ
OBJECT_IDENTIFIER.
Definition: asn1_node.h:27
#define JBXL_ASN1_SEQ_CNSTRCTD
SEQUENCE + CONSTRUCTED (構造化フラグ)
Definition: asn1_node.h:52
Buffer int2bin_DER(long int n)
Definition: asn1_tool.c:129
Buffer node2DER(Buffer pt, unsigned char node)
Definition: asn1_tool.c:70
int skip_DER_node(Buffer param, unsigned char node, int ls, int *lp)
Definition: asn1_tool.c:34
Buffer make_Buffer(int sz)
Buffer型変数のバッファ部をつくり出す.
Definition: buffer.c:71
void free_Buffer(Buffer *buf)
Buffer型変数のバッファ部を解放する
Definition: buffer.c:128
Buffer init_Buffer()
初期化したBuffer型変数を返す.
Definition: buffer.c:47
#define TRUE
Definition: common.h:226
#define FALSE
Definition: common.h:223
unsigned char ** buf
Definition: jpeg_tool.h:96
Definition: buffer.h:35
int bufsz
確保してあるバッファの大きさ - 1.
Definition: buffer.h:36
int vldsz
データの長さ.バイナリデータの場合も使用可能.文字列の場合は 0x00 を含まない.
Definition: buffer.h:37
unsigned char * buf
バッファの先頭へのポインタ.str[bufsz]は必ず 0x00となる.
Definition: buffer.h:39
int file_exist(const char *fn)
ファイルの存在を検査する.
Definition: tools.c:2337
FILE * file_chmod_open(const char *fn, const char *fm, mode_t mode)
ファイルの許可属性をmode へ変更した後,ファイルを fmモードでオープン
Definition: tools.c:2366
int save_tagged_Buffer(Buffer buf, FILE *fp, unsigned int mode, int prfm)
Bufferを指定された形式に従ってタグ付きでファイルに保存する.
Definition: xtools.c:956
Buffer read_tagged_Buffer(FILE *fp, unsigned int *mode)
save_tagged_Buffer() で保存したファイルから,Buffer をタグに従って読み込む.
Definition: xtools.c:1013
#define JBXL_FIO_ORIGINAL
Definition: xtools.h:27
#define JBXL_FIO_PRIV_KEY
Definition: xtools.h:23
#define JBXL_FIO_SPKI
Definition: xtools.h:25