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