Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /* 00002 * $Id: ossl_pkey_dh.c 36355 2012-07-10 13:57:11Z nobu $ 00003 * 'OpenSSL for Ruby' project 00004 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> 00005 * All rights reserved. 00006 */ 00007 /* 00008 * This program is licenced under the same licence as Ruby. 00009 * (See the file 'LICENCE'.) 00010 */ 00011 #if !defined(OPENSSL_NO_DH) 00012 00013 #include "ossl.h" 00014 00015 #define GetPKeyDH(obj, pkey) do { \ 00016 GetPKey((obj), (pkey)); \ 00017 if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_DH) { /* PARANOIA? */ \ 00018 ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \ 00019 } \ 00020 } while (0) 00021 00022 #define DH_HAS_PRIVATE(dh) ((dh)->priv_key) 00023 00024 #ifdef OSSL_ENGINE_ENABLED 00025 # define DH_PRIVATE(dh) (DH_HAS_PRIVATE(dh) || (dh)->engine) 00026 #else 00027 # define DH_PRIVATE(dh) DH_HAS_PRIVATE(dh) 00028 #endif 00029 00030 00031 /* 00032 * Classes 00033 */ 00034 VALUE cDH; 00035 VALUE eDHError; 00036 00037 /* 00038 * Public 00039 */ 00040 static VALUE 00041 dh_instance(VALUE klass, DH *dh) 00042 { 00043 EVP_PKEY *pkey; 00044 VALUE obj; 00045 00046 if (!dh) { 00047 return Qfalse; 00048 } 00049 if (!(pkey = EVP_PKEY_new())) { 00050 return Qfalse; 00051 } 00052 if (!EVP_PKEY_assign_DH(pkey, dh)) { 00053 EVP_PKEY_free(pkey); 00054 return Qfalse; 00055 } 00056 WrapPKey(klass, obj, pkey); 00057 00058 return obj; 00059 } 00060 00061 VALUE 00062 ossl_dh_new(EVP_PKEY *pkey) 00063 { 00064 VALUE obj; 00065 00066 if (!pkey) { 00067 obj = dh_instance(cDH, DH_new()); 00068 } else { 00069 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) { 00070 ossl_raise(rb_eTypeError, "Not a DH key!"); 00071 } 00072 WrapPKey(cDH, obj, pkey); 00073 } 00074 if (obj == Qfalse) { 00075 ossl_raise(eDHError, NULL); 00076 } 00077 00078 return obj; 00079 } 00080 00081 /* 00082 * Private 00083 */ 00084 #if defined(HAVE_DH_GENERATE_PARAMETERS_EX) && HAVE_BN_GENCB 00085 struct dh_blocking_gen_arg { 00086 DH *dh; 00087 int size; 00088 int gen; 00089 BN_GENCB *cb; 00090 int result; 00091 }; 00092 00093 static void * 00094 dh_blocking_gen(void *arg) 00095 { 00096 struct dh_blocking_gen_arg *gen = (struct dh_blocking_gen_arg *)arg; 00097 gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb); 00098 return 0; 00099 } 00100 #endif 00101 00102 static DH * 00103 dh_generate(int size, int gen) 00104 { 00105 #if defined(HAVE_DH_GENERATE_PARAMETERS_EX) && HAVE_BN_GENCB 00106 BN_GENCB cb; 00107 struct ossl_generate_cb_arg cb_arg; 00108 struct dh_blocking_gen_arg gen_arg; 00109 DH *dh = DH_new(); 00110 00111 if (!dh) return 0; 00112 00113 memset(&cb_arg, 0, sizeof(struct ossl_generate_cb_arg)); 00114 if (rb_block_given_p()) 00115 cb_arg.yield = 1; 00116 BN_GENCB_set(&cb, ossl_generate_cb_2, &cb_arg); 00117 gen_arg.dh = dh; 00118 gen_arg.size = size; 00119 gen_arg.gen = gen; 00120 gen_arg.cb = &cb; 00121 if (cb_arg.yield == 1) { 00122 /* we cannot release GVL when callback proc is supplied */ 00123 dh_blocking_gen(&gen_arg); 00124 } else { 00125 /* there's a chance to unblock */ 00126 rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); 00127 } 00128 00129 if (!gen_arg.result) { 00130 DH_free(dh); 00131 if (cb_arg.state) rb_jump_tag(cb_arg.state); 00132 return 0; 00133 } 00134 #else 00135 DH *dh; 00136 00137 dh = DH_generate_parameters(size, gen, rb_block_given_p() ? ossl_generate_cb : NULL, NULL); 00138 if (!dh) return 0; 00139 #endif 00140 00141 if (!DH_generate_key(dh)) { 00142 DH_free(dh); 00143 return 0; 00144 } 00145 00146 return dh; 00147 } 00148 00149 /* 00150 * call-seq: 00151 * DH.generate(size [, generator]) -> dh 00152 * 00153 * Creates a new DH instance from scratch by generating the private and public 00154 * components alike. 00155 * 00156 * === Parameters 00157 * * +size+ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. 00158 * * +generator+ is a small number > 1, typically 2 or 5. 00159 * 00160 */ 00161 static VALUE 00162 ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass) 00163 { 00164 DH *dh ; 00165 int g = 2; 00166 VALUE size, gen, obj; 00167 00168 if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) { 00169 g = NUM2INT(gen); 00170 } 00171 dh = dh_generate(NUM2INT(size), g); 00172 obj = dh_instance(klass, dh); 00173 if (obj == Qfalse) { 00174 DH_free(dh); 00175 ossl_raise(eDHError, NULL); 00176 } 00177 00178 return obj; 00179 } 00180 00181 /* 00182 * call-seq: 00183 * DH.new([size [, generator] | string]) -> dh 00184 * 00185 * Either generates a DH instance from scratch or by reading already existing 00186 * DH parameters from +string+. Note that when reading a DH instance from 00187 * data that was encoded from a DH instance by using DH#to_pem or DH#to_der 00188 * the result will *not* contain a public/private key pair yet. This needs to 00189 * be generated using DH#generate_key! first. 00190 * 00191 * === Parameters 00192 * * +size+ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. 00193 * * +generator+ is a small number > 1, typically 2 or 5. 00194 * * +string+ contains the DER or PEM encoded key. 00195 * 00196 * === Examples 00197 * DH.new # -> dh 00198 * DH.new(1024) # -> dh 00199 * DH.new(1024, 5) # -> dh 00200 * #Reading DH parameters 00201 * dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet 00202 * dh.generate_key! # -> dh with public and private key 00203 */ 00204 static VALUE 00205 ossl_dh_initialize(int argc, VALUE *argv, VALUE self) 00206 { 00207 EVP_PKEY *pkey; 00208 DH *dh; 00209 int g = 2; 00210 BIO *in; 00211 VALUE arg, gen; 00212 00213 GetPKey(self, pkey); 00214 if(rb_scan_args(argc, argv, "02", &arg, &gen) == 0) { 00215 dh = DH_new(); 00216 } 00217 else if (FIXNUM_P(arg)) { 00218 if (!NIL_P(gen)) { 00219 g = NUM2INT(gen); 00220 } 00221 if (!(dh = dh_generate(FIX2INT(arg), g))) { 00222 ossl_raise(eDHError, NULL); 00223 } 00224 } 00225 else { 00226 arg = ossl_to_der_if_possible(arg); 00227 in = ossl_obj2bio(arg); 00228 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); 00229 if (!dh){ 00230 OSSL_BIO_reset(in); 00231 dh = d2i_DHparams_bio(in, NULL); 00232 } 00233 BIO_free(in); 00234 if (!dh) { 00235 ossl_raise(eDHError, NULL); 00236 } 00237 } 00238 if (!EVP_PKEY_assign_DH(pkey, dh)) { 00239 DH_free(dh); 00240 ossl_raise(eDHError, NULL); 00241 } 00242 return self; 00243 } 00244 00245 /* 00246 * call-seq: 00247 * dh.public? -> true | false 00248 * 00249 * Indicates whether this DH instance has a public key associated with it or 00250 * not. The public key may be retrieved with DH#pub_key. 00251 */ 00252 static VALUE 00253 ossl_dh_is_public(VALUE self) 00254 { 00255 EVP_PKEY *pkey; 00256 00257 GetPKeyDH(self, pkey); 00258 00259 return (pkey->pkey.dh->pub_key) ? Qtrue : Qfalse; 00260 } 00261 00262 /* 00263 * call-seq: 00264 * dh.private? -> true | false 00265 * 00266 * Indicates whether this DH instance has a private key associated with it or 00267 * not. The private key may be retrieved with DH#priv_key. 00268 */ 00269 static VALUE 00270 ossl_dh_is_private(VALUE self) 00271 { 00272 EVP_PKEY *pkey; 00273 00274 GetPKeyDH(self, pkey); 00275 00276 return (DH_PRIVATE(pkey->pkey.dh)) ? Qtrue : Qfalse; 00277 } 00278 00279 /* 00280 * call-seq: 00281 * dh.to_pem -> aString 00282 * 00283 * Encodes this DH to its PEM encoding. Note that any existing per-session 00284 * public/private keys will *not* get encoded, just the Diffie-Hellman 00285 * parameters will be encoded. 00286 */ 00287 static VALUE 00288 ossl_dh_export(VALUE self) 00289 { 00290 EVP_PKEY *pkey; 00291 BIO *out; 00292 VALUE str; 00293 00294 GetPKeyDH(self, pkey); 00295 if (!(out = BIO_new(BIO_s_mem()))) { 00296 ossl_raise(eDHError, NULL); 00297 } 00298 if (!PEM_write_bio_DHparams(out, pkey->pkey.dh)) { 00299 BIO_free(out); 00300 ossl_raise(eDHError, NULL); 00301 } 00302 str = ossl_membio2str(out); 00303 00304 return str; 00305 } 00306 00307 /* 00308 * call-seq: 00309 * dh.to_der -> aString 00310 * 00311 * Encodes this DH to its DER encoding. Note that any existing per-session 00312 * public/private keys will *not* get encoded, just the Diffie-Hellman 00313 * parameters will be encoded. 00314 00315 */ 00316 static VALUE 00317 ossl_dh_to_der(VALUE self) 00318 { 00319 EVP_PKEY *pkey; 00320 unsigned char *p; 00321 long len; 00322 VALUE str; 00323 00324 GetPKeyDH(self, pkey); 00325 if((len = i2d_DHparams(pkey->pkey.dh, NULL)) <= 0) 00326 ossl_raise(eDHError, NULL); 00327 str = rb_str_new(0, len); 00328 p = (unsigned char *)RSTRING_PTR(str); 00329 if(i2d_DHparams(pkey->pkey.dh, &p) < 0) 00330 ossl_raise(eDHError, NULL); 00331 ossl_str_adjust(str, p); 00332 00333 return str; 00334 } 00335 00336 /* 00337 * call-seq: 00338 * dh.params -> hash 00339 * 00340 * Stores all parameters of key to the hash 00341 * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! 00342 * Don't use :-)) (I's up to you) 00343 */ 00344 static VALUE 00345 ossl_dh_get_params(VALUE self) 00346 { 00347 EVP_PKEY *pkey; 00348 VALUE hash; 00349 00350 GetPKeyDH(self, pkey); 00351 00352 hash = rb_hash_new(); 00353 00354 rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dh->p)); 00355 rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dh->g)); 00356 rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dh->pub_key)); 00357 rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dh->priv_key)); 00358 00359 return hash; 00360 } 00361 00362 /* 00363 * call-seq: 00364 * dh.to_text -> aString 00365 * 00366 * Prints all parameters of key to buffer 00367 * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! 00368 * Don't use :-)) (I's up to you) 00369 */ 00370 static VALUE 00371 ossl_dh_to_text(VALUE self) 00372 { 00373 EVP_PKEY *pkey; 00374 BIO *out; 00375 VALUE str; 00376 00377 GetPKeyDH(self, pkey); 00378 if (!(out = BIO_new(BIO_s_mem()))) { 00379 ossl_raise(eDHError, NULL); 00380 } 00381 if (!DHparams_print(out, pkey->pkey.dh)) { 00382 BIO_free(out); 00383 ossl_raise(eDHError, NULL); 00384 } 00385 str = ossl_membio2str(out); 00386 00387 return str; 00388 } 00389 00390 /* 00391 * call-seq: 00392 * dh.public_key -> aDH 00393 * 00394 * Returns a new DH instance that carries just the public information, i.e. 00395 * the prime +p+ and the generator +g+, but no public/private key yet. Such 00396 * a pair may be generated using DH#generate_key!. The "public key" needed 00397 * for a key exchange with DH#compute_key is considered as per-session 00398 * information and may be retrieved with DH#pub_key once a key pair has 00399 * been generated. 00400 * If the current instance already contains private information (and thus a 00401 * valid public/private key pair), this information will no longer be present 00402 * in the new instance generated by DH#public_key. This feature is helpful for 00403 * publishing the Diffie-Hellman parameters without leaking any of the private 00404 * per-session information. 00405 * 00406 * === Example 00407 * dh = OpenSSL::PKey::DH.new(2048) # has public and private key set 00408 * public_key = dh.public_key # contains only prime and generator 00409 * parameters = public_key.to_der # it's safe to publish this 00410 */ 00411 static VALUE 00412 ossl_dh_to_public_key(VALUE self) 00413 { 00414 EVP_PKEY *pkey; 00415 DH *dh; 00416 VALUE obj; 00417 00418 GetPKeyDH(self, pkey); 00419 dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */ 00420 obj = dh_instance(CLASS_OF(self), dh); 00421 if (obj == Qfalse) { 00422 DH_free(dh); 00423 ossl_raise(eDHError, NULL); 00424 } 00425 00426 return obj; 00427 } 00428 00429 /* 00430 * call-seq: 00431 * dh.check_params -> true | false 00432 * 00433 * Validates the Diffie-Hellman parameters associated with this instance. 00434 * It checks whether a safe prime and a suitable generator are used. If this 00435 * is not the case, +false+ is returned. 00436 */ 00437 static VALUE 00438 ossl_dh_check_params(VALUE self) 00439 { 00440 DH *dh; 00441 EVP_PKEY *pkey; 00442 int codes; 00443 00444 GetPKeyDH(self, pkey); 00445 dh = pkey->pkey.dh; 00446 00447 if (!DH_check(dh, &codes)) { 00448 return Qfalse; 00449 } 00450 00451 return codes == 0 ? Qtrue : Qfalse; 00452 } 00453 00454 /* 00455 * call-seq: 00456 * dh.generate_key! -> self 00457 * 00458 * Generates a private and public key unless a private key already exists. 00459 * If this DH instance was generated from public DH parameters (e.g. by 00460 * encoding the result of DH#public_key), then this method needs to be 00461 * called first in order to generate the per-session keys before performing 00462 * the actual key exchange. 00463 * 00464 * === Example 00465 * dh = OpenSSL::PKey::DH.new(2048) 00466 * public_key = dh.public_key #contains no private/public key yet 00467 * public_key.generate_key! 00468 * puts public_key.private? # => true 00469 */ 00470 static VALUE 00471 ossl_dh_generate_key(VALUE self) 00472 { 00473 DH *dh; 00474 EVP_PKEY *pkey; 00475 00476 GetPKeyDH(self, pkey); 00477 dh = pkey->pkey.dh; 00478 00479 if (!DH_generate_key(dh)) 00480 ossl_raise(eDHError, "Failed to generate key"); 00481 return self; 00482 } 00483 00484 /* 00485 * call-seq: 00486 * dh.compute_key(pub_bn) -> aString 00487 * 00488 * Returns a String containing a shared secret computed from the other party's public value. 00489 * See DH_compute_key() for further information. 00490 * 00491 * === Parameters 00492 * * +pub_bn+ is a OpenSSL::BN, *not* the DH instance returned by 00493 * DH#public_key as that contains the DH parameters only. 00494 */ 00495 static VALUE 00496 ossl_dh_compute_key(VALUE self, VALUE pub) 00497 { 00498 DH *dh; 00499 EVP_PKEY *pkey; 00500 BIGNUM *pub_key; 00501 VALUE str; 00502 int len; 00503 00504 GetPKeyDH(self, pkey); 00505 dh = pkey->pkey.dh; 00506 pub_key = GetBNPtr(pub); 00507 len = DH_size(dh); 00508 str = rb_str_new(0, len); 00509 if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) { 00510 ossl_raise(eDHError, NULL); 00511 } 00512 rb_str_set_len(str, len); 00513 00514 return str; 00515 } 00516 00517 OSSL_PKEY_BN(dh, p) 00518 OSSL_PKEY_BN(dh, g) 00519 OSSL_PKEY_BN(dh, pub_key) 00520 OSSL_PKEY_BN(dh, priv_key) 00521 00522 /* 00523 * -----BEGIN DH PARAMETERS----- 00524 * MEYCQQD0zXHljRg/mJ9PYLACLv58Cd8VxBxxY7oEuCeURMiTqEhMym16rhhKgZG2 00525 * zk2O9uUIBIxSj+NKMURHGaFKyIvLAgEC 00526 * -----END DH PARAMETERS----- 00527 */ 00528 static unsigned char DEFAULT_DH_512_PRIM[] = { 00529 0xf4, 0xcd, 0x71, 0xe5, 0x8d, 0x18, 0x3f, 0x98, 00530 0x9f, 0x4f, 0x60, 0xb0, 0x02, 0x2e, 0xfe, 0x7c, 00531 0x09, 0xdf, 0x15, 0xc4, 0x1c, 0x71, 0x63, 0xba, 00532 0x04, 0xb8, 0x27, 0x94, 0x44, 0xc8, 0x93, 0xa8, 00533 0x48, 0x4c, 0xca, 0x6d, 0x7a, 0xae, 0x18, 0x4a, 00534 0x81, 0x91, 0xb6, 0xce, 0x4d, 0x8e, 0xf6, 0xe5, 00535 0x08, 0x04, 0x8c, 0x52, 0x8f, 0xe3, 0x4a, 0x31, 00536 0x44, 0x47, 0x19, 0xa1, 0x4a, 0xc8, 0x8b, 0xcb, 00537 }; 00538 static unsigned char DEFAULT_DH_512_GEN[] = { 0x02 }; 00539 DH *OSSL_DEFAULT_DH_512 = NULL; 00540 00541 /* 00542 * -----BEGIN DH PARAMETERS----- 00543 * MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ 00544 * AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR 00545 * T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC 00546 * -----END DH PARAMETERS----- 00547 */ 00548 static unsigned char DEFAULT_DH_1024_PRIM[] = { 00549 0x9d, 0x25, 0x39, 0x5c, 0xb4, 0x54, 0x8a, 0xff, 00550 0x25, 0xe6, 0xd6, 0x9f, 0x4c, 0xc3, 0xc1, 0x8d, 00551 0xa1, 0xfa, 0xba, 0x88, 0x4c, 0x53, 0xa9, 0x74, 00552 0xda, 0xfa, 0xba, 0x0b, 0x20, 0xbe, 0x40, 0xd7, 00553 0xba, 0xe7, 0x1d, 0x70, 0x28, 0x61, 0x60, 0x4c, 00554 0x49, 0x01, 0x5f, 0xd9, 0x0f, 0x60, 0x16, 0x3d, 00555 0xba, 0xd3, 0xa9, 0x5e, 0xfa, 0x98, 0x64, 0x60, 00556 0x26, 0x0e, 0x04, 0x75, 0xd8, 0x13, 0xd7, 0x31, 00557 0xb4, 0x8e, 0xad, 0xeb, 0x9c, 0x57, 0x4c, 0x8f, 00558 0x65, 0xf3, 0x90, 0x16, 0x31, 0xdc, 0x15, 0x6f, 00559 0x7d, 0x1d, 0x00, 0xae, 0x76, 0xf2, 0xd1, 0x11, 00560 0xd1, 0x4f, 0x88, 0x7b, 0x29, 0x9f, 0xf6, 0xce, 00561 0x68, 0xef, 0x57, 0xe7, 0x85, 0xf2, 0x40, 0x54, 00562 0x1c, 0x12, 0x40, 0xa2, 0x35, 0x25, 0xcf, 0x12, 00563 0xa3, 0xe1, 0x07, 0x8e, 0xdb, 0x1d, 0xb4, 0x14, 00564 0xff, 0x57, 0xe7, 0x19, 0x8d, 0x51, 0x77, 0x83 00565 }; 00566 static unsigned char DEFAULT_DH_1024_GEN[] = { 0x02 }; 00567 DH *OSSL_DEFAULT_DH_1024 = NULL; 00568 00569 static DH* 00570 ossl_create_dh(unsigned char *p, size_t plen, unsigned char *g, size_t glen) 00571 { 00572 DH *dh; 00573 00574 if ((dh = DH_new()) == NULL) ossl_raise(eDHError, NULL); 00575 dh->p = BN_bin2bn(p, rb_long2int(plen), NULL); 00576 dh->g = BN_bin2bn(g, rb_long2int(glen), NULL); 00577 if (dh->p == NULL || dh->g == NULL){ 00578 DH_free(dh); 00579 ossl_raise(eDHError, NULL); 00580 } 00581 00582 return dh; 00583 } 00584 00585 /* 00586 * INIT 00587 */ 00588 void 00589 Init_ossl_dh() 00590 { 00591 #if 0 00592 mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */ 00593 mPKey = rb_define_module_under(mOSSL, "PKey"); 00594 #endif 00595 00596 /* Document-class: OpenSSL::PKey::DHError 00597 * 00598 * Generic exception that is raised if an operation on a DH PKey 00599 * fails unexpectedly or in case an instantiation of an instance of DH 00600 * fails due to non-conformant input data. 00601 */ 00602 eDHError = rb_define_class_under(mPKey, "DHError", ePKeyError); 00603 /* Document-class: OpenSSL::PKey::DH 00604 * 00605 * An implementation of the Diffie-Hellman key exchange protocol based on 00606 * discrete logarithms in finite fields, the same basis that DSA is built 00607 * on. 00608 * 00609 * === Accessor methods for the Diffie-Hellman parameters 00610 * * DH#p 00611 * The prime (an OpenSSL::BN) of the Diffie-Hellman parameters. 00612 * * DH#g 00613 * The generator (an OpenSSL::BN) g of the Diffie-Hellman parameters. 00614 * * DH#pub_key 00615 * The per-session public key (an OpenSSL::BN) matching the private key. 00616 * This needs to be passed to DH#compute_key. 00617 * * DH#priv_key 00618 * The per-session private key, an OpenSSL::BN. 00619 * 00620 * === Example of a key exchange 00621 * dh1 = OpenSSL::PKey::DH.new(2048) 00622 * params = dh1.public_key.to_der #you may send this publicly to the participating party 00623 * dh2 = OpenSSL::PKey::DH.new(der) 00624 * dh2.generate_key! #generate the per-session key pair 00625 * symm_key1 = dh1.compute_key(dh2.pub_key) 00626 * symm_key2 = dh2.compute_key(dh1.pub_key) 00627 * 00628 * puts symm_key1 == symm_key2 # => true 00629 */ 00630 cDH = rb_define_class_under(mPKey, "DH", cPKey); 00631 rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1); 00632 rb_define_method(cDH, "initialize", ossl_dh_initialize, -1); 00633 rb_define_method(cDH, "public?", ossl_dh_is_public, 0); 00634 rb_define_method(cDH, "private?", ossl_dh_is_private, 0); 00635 rb_define_method(cDH, "to_text", ossl_dh_to_text, 0); 00636 rb_define_method(cDH, "export", ossl_dh_export, 0); 00637 rb_define_alias(cDH, "to_pem", "export"); 00638 rb_define_alias(cDH, "to_s", "export"); 00639 rb_define_method(cDH, "to_der", ossl_dh_to_der, 0); 00640 rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0); 00641 rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0); 00642 rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0); 00643 rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1); 00644 00645 DEF_OSSL_PKEY_BN(cDH, dh, p); 00646 DEF_OSSL_PKEY_BN(cDH, dh, g); 00647 DEF_OSSL_PKEY_BN(cDH, dh, pub_key); 00648 DEF_OSSL_PKEY_BN(cDH, dh, priv_key); 00649 rb_define_method(cDH, "params", ossl_dh_get_params, 0); 00650 00651 OSSL_DEFAULT_DH_512 = ossl_create_dh( 00652 DEFAULT_DH_512_PRIM, sizeof(DEFAULT_DH_512_PRIM), 00653 DEFAULT_DH_512_GEN, sizeof(DEFAULT_DH_512_GEN)); 00654 OSSL_DEFAULT_DH_1024 = ossl_create_dh( 00655 DEFAULT_DH_1024_PRIM, sizeof(DEFAULT_DH_1024_PRIM), 00656 DEFAULT_DH_1024_GEN, sizeof(DEFAULT_DH_1024_GEN)); 00657 } 00658 00659 #else /* defined NO_DH */ 00660 void 00661 Init_ossl_dh() 00662 { 00663 } 00664 #endif /* NO_DH */ 00665 00666