ext/openssl/ossl_pkey_dh.c

Go to the documentation of this file.
00001 /*
00002  * $Id: ossl_pkey_dh.c 45113 2014-02-22 05:56:02Z naruse $
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.export -> aString
00282  *     dh.to_pem -> aString
00283  *     dh.to_s -> aString
00284  *
00285  * Encodes this DH to its PEM encoding. Note that any existing per-session
00286  * public/private keys will *not* get encoded, just the Diffie-Hellman
00287  * parameters will be encoded.
00288  */
00289 static VALUE
00290 ossl_dh_export(VALUE self)
00291 {
00292     EVP_PKEY *pkey;
00293     BIO *out;
00294     VALUE str;
00295 
00296     GetPKeyDH(self, pkey);
00297     if (!(out = BIO_new(BIO_s_mem()))) {
00298         ossl_raise(eDHError, NULL);
00299     }
00300     if (!PEM_write_bio_DHparams(out, pkey->pkey.dh)) {
00301         BIO_free(out);
00302         ossl_raise(eDHError, NULL);
00303     }
00304     str = ossl_membio2str(out);
00305 
00306     return str;
00307 }
00308 
00309 /*
00310  *  call-seq:
00311  *     dh.to_der -> aString
00312  *
00313  * Encodes this DH to its DER encoding. Note that any existing per-session
00314  * public/private keys will *not* get encoded, just the Diffie-Hellman
00315  * parameters will be encoded.
00316 
00317  */
00318 static VALUE
00319 ossl_dh_to_der(VALUE self)
00320 {
00321     EVP_PKEY *pkey;
00322     unsigned char *p;
00323     long len;
00324     VALUE str;
00325 
00326     GetPKeyDH(self, pkey);
00327     if((len = i2d_DHparams(pkey->pkey.dh, NULL)) <= 0)
00328         ossl_raise(eDHError, NULL);
00329     str = rb_str_new(0, len);
00330     p = (unsigned char *)RSTRING_PTR(str);
00331     if(i2d_DHparams(pkey->pkey.dh, &p) < 0)
00332         ossl_raise(eDHError, NULL);
00333     ossl_str_adjust(str, p);
00334 
00335     return str;
00336 }
00337 
00338 /*
00339  *  call-seq:
00340  *     dh.params -> hash
00341  *
00342  * Stores all parameters of key to the hash
00343  * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
00344  * Don't use :-)) (I's up to you)
00345  */
00346 static VALUE
00347 ossl_dh_get_params(VALUE self)
00348 {
00349     EVP_PKEY *pkey;
00350     VALUE hash;
00351 
00352     GetPKeyDH(self, pkey);
00353 
00354     hash = rb_hash_new();
00355 
00356     rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dh->p));
00357     rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dh->g));
00358     rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dh->pub_key));
00359     rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dh->priv_key));
00360 
00361     return hash;
00362 }
00363 
00364 /*
00365  *  call-seq:
00366  *     dh.to_text -> aString
00367  *
00368  * Prints all parameters of key to buffer
00369  * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
00370  * Don't use :-)) (I's up to you)
00371  */
00372 static VALUE
00373 ossl_dh_to_text(VALUE self)
00374 {
00375     EVP_PKEY *pkey;
00376     BIO *out;
00377     VALUE str;
00378 
00379     GetPKeyDH(self, pkey);
00380     if (!(out = BIO_new(BIO_s_mem()))) {
00381         ossl_raise(eDHError, NULL);
00382     }
00383     if (!DHparams_print(out, pkey->pkey.dh)) {
00384         BIO_free(out);
00385         ossl_raise(eDHError, NULL);
00386     }
00387     str = ossl_membio2str(out);
00388 
00389     return str;
00390 }
00391 
00392 /*
00393  *  call-seq:
00394  *     dh.public_key -> aDH
00395  *
00396  * Returns a new DH instance that carries just the public information, i.e.
00397  * the prime +p+ and the generator +g+, but no public/private key yet. Such
00398  * a pair may be generated using DH#generate_key!. The "public key" needed
00399  * for a key exchange with DH#compute_key is considered as per-session
00400  * information and may be retrieved with DH#pub_key once a key pair has
00401  * been generated.
00402  * If the current instance already contains private information (and thus a
00403  * valid public/private key pair), this information will no longer be present
00404  * in the new instance generated by DH#public_key. This feature is helpful for
00405  * publishing the Diffie-Hellman parameters without leaking any of the private
00406  * per-session information.
00407  *
00408  * === Example
00409  *  dh = OpenSSL::PKey::DH.new(2048) # has public and private key set
00410  *  public_key = dh.public_key # contains only prime and generator
00411  *  parameters = public_key.to_der # it's safe to publish this
00412  */
00413 static VALUE
00414 ossl_dh_to_public_key(VALUE self)
00415 {
00416     EVP_PKEY *pkey;
00417     DH *dh;
00418     VALUE obj;
00419 
00420     GetPKeyDH(self, pkey);
00421     dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */
00422     obj = dh_instance(CLASS_OF(self), dh);
00423     if (obj == Qfalse) {
00424         DH_free(dh);
00425         ossl_raise(eDHError, NULL);
00426     }
00427 
00428     return obj;
00429 }
00430 
00431 /*
00432  *  call-seq:
00433  *     dh.params_ok? -> true | false
00434  *
00435  * Validates the Diffie-Hellman parameters associated with this instance.
00436  * It checks whether a safe prime and a suitable generator are used. If this
00437  * is not the case, +false+ is returned.
00438  */
00439 static VALUE
00440 ossl_dh_check_params(VALUE self)
00441 {
00442     DH *dh;
00443     EVP_PKEY *pkey;
00444     int codes;
00445 
00446     GetPKeyDH(self, pkey);
00447     dh = pkey->pkey.dh;
00448 
00449     if (!DH_check(dh, &codes)) {
00450         return Qfalse;
00451     }
00452 
00453     return codes == 0 ? Qtrue : Qfalse;
00454 }
00455 
00456 /*
00457  *  call-seq:
00458  *     dh.generate_key! -> self
00459  *
00460  * Generates a private and public key unless a private key already exists.
00461  * If this DH instance was generated from public DH parameters (e.g. by
00462  * encoding the result of DH#public_key), then this method needs to be
00463  * called first in order to generate the per-session keys before performing
00464  * the actual key exchange.
00465  *
00466  * === Example
00467  *   dh = OpenSSL::PKey::DH.new(2048)
00468  *   public_key = dh.public_key #contains no private/public key yet
00469  *   public_key.generate_key!
00470  *   puts public_key.private? # => true
00471  */
00472 static VALUE
00473 ossl_dh_generate_key(VALUE self)
00474 {
00475     DH *dh;
00476     EVP_PKEY *pkey;
00477 
00478     GetPKeyDH(self, pkey);
00479     dh = pkey->pkey.dh;
00480 
00481     if (!DH_generate_key(dh))
00482         ossl_raise(eDHError, "Failed to generate key");
00483     return self;
00484 }
00485 
00486 /*
00487  *  call-seq:
00488  *     dh.compute_key(pub_bn) -> aString
00489  *
00490  * Returns a String containing a shared secret computed from the other party's public value.
00491  * See DH_compute_key() for further information.
00492  *
00493  * === Parameters
00494  * * +pub_bn+ is a OpenSSL::BN, *not* the DH instance returned by
00495  * DH#public_key as that contains the DH parameters only.
00496  */
00497 static VALUE
00498 ossl_dh_compute_key(VALUE self, VALUE pub)
00499 {
00500     DH *dh;
00501     EVP_PKEY *pkey;
00502     BIGNUM *pub_key;
00503     VALUE str;
00504     int len;
00505 
00506     GetPKeyDH(self, pkey);
00507     dh = pkey->pkey.dh;
00508     pub_key = GetBNPtr(pub);
00509     len = DH_size(dh);
00510     str = rb_str_new(0, len);
00511     if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) {
00512         ossl_raise(eDHError, NULL);
00513     }
00514     rb_str_set_len(str, len);
00515 
00516     return str;
00517 }
00518 
00519 OSSL_PKEY_BN(dh, p)
00520 OSSL_PKEY_BN(dh, g)
00521 OSSL_PKEY_BN(dh, pub_key)
00522 OSSL_PKEY_BN(dh, priv_key)
00523 
00524 /*
00525  * -----BEGIN DH PARAMETERS-----
00526  * MEYCQQD0zXHljRg/mJ9PYLACLv58Cd8VxBxxY7oEuCeURMiTqEhMym16rhhKgZG2
00527  * zk2O9uUIBIxSj+NKMURHGaFKyIvLAgEC
00528  * -----END DH PARAMETERS-----
00529  */
00530 static unsigned char DEFAULT_DH_512_PRIM[] = {
00531     0xf4, 0xcd, 0x71, 0xe5, 0x8d, 0x18, 0x3f, 0x98,
00532     0x9f, 0x4f, 0x60, 0xb0, 0x02, 0x2e, 0xfe, 0x7c,
00533     0x09, 0xdf, 0x15, 0xc4, 0x1c, 0x71, 0x63, 0xba,
00534     0x04, 0xb8, 0x27, 0x94, 0x44, 0xc8, 0x93, 0xa8,
00535     0x48, 0x4c, 0xca, 0x6d, 0x7a, 0xae, 0x18, 0x4a,
00536     0x81, 0x91, 0xb6, 0xce, 0x4d, 0x8e, 0xf6, 0xe5,
00537     0x08, 0x04, 0x8c, 0x52, 0x8f, 0xe3, 0x4a, 0x31,
00538     0x44, 0x47, 0x19, 0xa1, 0x4a, 0xc8, 0x8b, 0xcb,
00539 };
00540 static unsigned char DEFAULT_DH_512_GEN[] = { 0x02 };
00541 DH *OSSL_DEFAULT_DH_512 = NULL;
00542 
00543 /*
00544  * -----BEGIN DH PARAMETERS-----
00545  * MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ
00546  * AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR
00547  * T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC
00548  * -----END DH PARAMETERS-----
00549  */
00550 static unsigned char DEFAULT_DH_1024_PRIM[] = {
00551     0x9d, 0x25, 0x39, 0x5c, 0xb4, 0x54, 0x8a, 0xff,
00552     0x25, 0xe6, 0xd6, 0x9f, 0x4c, 0xc3, 0xc1, 0x8d,
00553     0xa1, 0xfa, 0xba, 0x88, 0x4c, 0x53, 0xa9, 0x74,
00554     0xda, 0xfa, 0xba, 0x0b, 0x20, 0xbe, 0x40, 0xd7,
00555     0xba, 0xe7, 0x1d, 0x70, 0x28, 0x61, 0x60, 0x4c,
00556     0x49, 0x01, 0x5f, 0xd9, 0x0f, 0x60, 0x16, 0x3d,
00557     0xba, 0xd3, 0xa9, 0x5e, 0xfa, 0x98, 0x64, 0x60,
00558     0x26, 0x0e, 0x04, 0x75, 0xd8, 0x13, 0xd7, 0x31,
00559     0xb4, 0x8e, 0xad, 0xeb, 0x9c, 0x57, 0x4c, 0x8f,
00560     0x65, 0xf3, 0x90, 0x16, 0x31, 0xdc, 0x15, 0x6f,
00561     0x7d, 0x1d, 0x00, 0xae, 0x76, 0xf2, 0xd1, 0x11,
00562     0xd1, 0x4f, 0x88, 0x7b, 0x29, 0x9f, 0xf6, 0xce,
00563     0x68, 0xef, 0x57, 0xe7, 0x85, 0xf2, 0x40, 0x54,
00564     0x1c, 0x12, 0x40, 0xa2, 0x35, 0x25, 0xcf, 0x12,
00565     0xa3, 0xe1, 0x07, 0x8e, 0xdb, 0x1d, 0xb4, 0x14,
00566     0xff, 0x57, 0xe7, 0x19, 0x8d, 0x51, 0x77, 0x83
00567 };
00568 static unsigned char DEFAULT_DH_1024_GEN[] = { 0x02 };
00569 DH *OSSL_DEFAULT_DH_1024 = NULL;
00570 
00571 static DH*
00572 ossl_create_dh(unsigned char *p, size_t plen, unsigned char *g, size_t glen)
00573 {
00574     DH *dh;
00575 
00576     if ((dh = DH_new()) == NULL) ossl_raise(eDHError, NULL);
00577     dh->p = BN_bin2bn(p, rb_long2int(plen), NULL);
00578     dh->g = BN_bin2bn(g, rb_long2int(glen), NULL);
00579     if (dh->p == NULL || dh->g == NULL){
00580         DH_free(dh);
00581         ossl_raise(eDHError, NULL);
00582     }
00583 
00584     return dh;
00585 }
00586 
00587 /*
00588  * INIT
00589  */
00590 void
00591 Init_ossl_dh()
00592 {
00593 #if 0
00594     mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */
00595     mPKey = rb_define_module_under(mOSSL, "PKey");
00596 #endif
00597 
00598     /* Document-class: OpenSSL::PKey::DHError
00599      *
00600      * Generic exception that is raised if an operation on a DH PKey
00601      * fails unexpectedly or in case an instantiation of an instance of DH
00602      * fails due to non-conformant input data.
00603      */
00604     eDHError = rb_define_class_under(mPKey, "DHError", ePKeyError);
00605     /* Document-class: OpenSSL::PKey::DH
00606      *
00607      * An implementation of the Diffie-Hellman key exchange protocol based on
00608      * discrete logarithms in finite fields, the same basis that DSA is built
00609      * on.
00610      *
00611      * === Accessor methods for the Diffie-Hellman parameters
00612      * * DH#p
00613      * The prime (an OpenSSL::BN) of the Diffie-Hellman parameters.
00614      * * DH#g
00615      * The generator (an OpenSSL::BN) g of the Diffie-Hellman parameters.
00616      * * DH#pub_key
00617      * The per-session public key (an OpenSSL::BN) matching the private key.
00618      * This needs to be passed to DH#compute_key.
00619      * * DH#priv_key
00620      * The per-session private key, an OpenSSL::BN.
00621      *
00622      * === Example of a key exchange
00623      *  dh1 = OpenSSL::PKey::DH.new(2048)
00624      *  der = dh1.public_key.to_der #you may send this publicly to the participating party
00625      *  dh2 = OpenSSL::PKey::DH.new(der)
00626      *  dh2.generate_key! #generate the per-session key pair
00627      *  symm_key1 = dh1.compute_key(dh2.pub_key)
00628      *  symm_key2 = dh2.compute_key(dh1.pub_key)
00629      *
00630      *  puts symm_key1 == symm_key2 # => true
00631      */
00632     cDH = rb_define_class_under(mPKey, "DH", cPKey);
00633     rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1);
00634     rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
00635     rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
00636     rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
00637     rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
00638     rb_define_method(cDH, "export", ossl_dh_export, 0);
00639     rb_define_alias(cDH, "to_pem", "export");
00640     rb_define_alias(cDH, "to_s", "export");
00641     rb_define_method(cDH, "to_der", ossl_dh_to_der, 0);
00642     rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0);
00643     rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0);
00644     rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0);
00645     rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1);
00646 
00647     DEF_OSSL_PKEY_BN(cDH, dh, p);
00648     DEF_OSSL_PKEY_BN(cDH, dh, g);
00649     DEF_OSSL_PKEY_BN(cDH, dh, pub_key);
00650     DEF_OSSL_PKEY_BN(cDH, dh, priv_key);
00651     rb_define_method(cDH, "params", ossl_dh_get_params, 0);
00652 
00653     OSSL_DEFAULT_DH_512 = ossl_create_dh(
00654         DEFAULT_DH_512_PRIM, sizeof(DEFAULT_DH_512_PRIM),
00655         DEFAULT_DH_512_GEN, sizeof(DEFAULT_DH_512_GEN));
00656     OSSL_DEFAULT_DH_1024 = ossl_create_dh(
00657         DEFAULT_DH_1024_PRIM, sizeof(DEFAULT_DH_1024_PRIM),
00658         DEFAULT_DH_1024_GEN, sizeof(DEFAULT_DH_1024_GEN));
00659 }
00660 
00661 #else /* defined NO_DH */
00662 void
00663 Init_ossl_dh()
00664 {
00665 }
00666 #endif /* NO_DH */
00667 

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7