/* * call-seq: * OpenSSL::PKey.read(string [, pwd ] ) -> PKey * OpenSSL::PKey.read(file [, pwd ]) -> PKey * * === Parameters * * +string+ is a DER- or PEM-encoded string containing an arbitrary private * or public key. * * +file+ is an instance of +File+ containing a DER- or PEM-encoded * arbitrary private or public key. * * +pwd+ is an optional password in case +string+ or +file+ is an encrypted * PEM resource. */ static VALUE ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; BIO *bio; VALUE data, pass; char *passwd = NULL; rb_scan_args(argc, argv, "11", &data, &pass); bio = ossl_obj2bio(data); if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) { OSSL_BIO_reset(bio); if (!NIL_P(pass)) { passwd = StringValuePtr(pass); } if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) { OSSL_BIO_reset(bio); if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) { OSSL_BIO_reset(bio); if (!NIL_P(pass)) { passwd = StringValuePtr(pass); } pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd); } } } BIO_free(bio); if (!pkey) ossl_raise(rb_eArgError, "Could not parse PKey"); return ossl_pkey_new(pkey); }
/* call-seq: * OpenSSL::PKey::EC.new() * OpenSSL::PKey::EC.new(ec_key) * OpenSSL::PKey::EC.new(ec_group) * OpenSSL::PKey::EC.new("secp112r1") * OpenSSL::PKey::EC.new(pem_string) * OpenSSL::PKey::EC.new(pem_string [, pwd]) * OpenSSL::PKey::EC.new(der_string) * * See the OpenSSL documentation for: * EC_KEY_* */ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; EC_KEY *ec; VALUE arg, pass; GetPKey(self, pkey); if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) ossl_raise(eECError, "EC_KEY already initialized"); rb_scan_args(argc, argv, "02", &arg, &pass); if (NIL_P(arg)) { if (!(ec = EC_KEY_new())) ossl_raise(eECError, NULL); } else if (rb_obj_is_kind_of(arg, cEC)) { EC_KEY *other_ec = NULL; SafeRequire_EC_KEY(arg, other_ec); if (!(ec = EC_KEY_dup(other_ec))) ossl_raise(eECError, NULL); } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { ec = ec_key_new_from_group(arg); } else { BIO *in; pass = ossl_pem_passwd_value(pass); in = ossl_obj2bio(arg); ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass); if (!ec) { OSSL_BIO_reset(in); ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass); } if (!ec) { OSSL_BIO_reset(in); ec = d2i_ECPrivateKey_bio(in, NULL); } if (!ec) { OSSL_BIO_reset(in); ec = d2i_EC_PUBKEY_bio(in, NULL); } BIO_free(in); if (!ec) { ossl_clear_error(); ec = ec_key_new_from_group(arg); } } if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { EC_KEY_free(ec); ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); } rb_iv_set(self, "@group", Qnil); return self; }
/* * call-seq: * PKCS7.new => pkcs7 * PKCS7.new(string) => pkcs7 * * Many methods in this class aren't documented. */ static VALUE ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) { PKCS7 *p7, *pkcs = DATA_PTR(self); BIO *in; VALUE arg; if(rb_scan_args(argc, argv, "01", &arg) == 0) return self; arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(arg); p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL); DATA_PTR(self) = pkcs; if (!p7) { OSSL_BIO_reset(in); p7 = d2i_PKCS7_bio(in, &pkcs); if (!p7) ossl_raise(rb_eArgError, "Could not parse the PKCS7"); DATA_PTR(self) = pkcs; } BIO_free(in); ossl_pkcs7_set_data(self, Qnil); ossl_pkcs7_set_err_string(self, Qnil); return self; }
static VALUE ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self) { BIO *in; X509_CRL *crl = rb_rdata_fetch(self); X509_CRL *x = crl; VALUE arg; if (rb_scan_args(argc, argv, "01", &arg) == 0) { return self; } arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(arg); crl = PEM_read_bio_X509_CRL(in, &x, NULL, NULL); rb_rdata_store(self, x); if (!crl) { OSSL_BIO_reset(in); crl = d2i_X509_CRL_bio(in, &x); rb_rdata_store(self, x); } BIO_free(in); if (!crl) ossl_raise(eX509CRLError, NULL); return self; }
static VALUE ossl_cms_initialize(int argc, VALUE *argv, VALUE self) { CMS_ContentInfo *cms, *out = DATA_PTR(self); BIO *in; VALUE arg; if(rb_scan_args(argc, argv, "01", &arg) == 0) return self; arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(arg); cms = PEM_read_bio_CMS(in, &out, NULL, NULL); if (!cms) { OSSL_BIO_reset(in); cms = d2i_CMS_bio(in, &out); if (!cms) { BIO_free(in); CMS_ContentInfo_free(out); DATA_PTR(self) = NULL; ossl_raise(rb_eArgError, "Could not parse the CMS"); } } DATA_PTR(self) = out; BIO_free(in); ossl_cms_set_data(self, Qnil); ossl_cms_set_err_string(self, Qnil); return self; }
static VALUE ossl_cms_s_read_cms(VALUE klass, VALUE arg) { BIO *in; CMS_ContentInfo *cms, *out; VALUE ret; arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(arg); out = CMS_ContentInfo_new(); cms = PEM_read_bio_CMS(in, &out, NULL, NULL); if (!cms) { OSSL_BIO_reset(in); cms = d2i_CMS_bio(in, &out); if (!cms) { BIO_free(in); CMS_ContentInfo_free(out); ossl_raise(rb_eArgError, "Could not parse the CMS"); } } WrapCMS(cCMS, ret, cms); BIO_free(in); ossl_cms_set_data(ret, Qnil); ossl_cms_set_err_string(ret, Qnil); return ret; }
/* * call-seq: * DH.new([size [, generator] | string]) -> dh * * Either generates a DH instance from scratch or by reading already existing * DH parameters from +string+. Note that when reading a DH instance from * data that was encoded from a DH instance by using DH#to_pem or DH#to_der * the result will *not* contain a public/private key pair yet. This needs to * be generated using DH#generate_key! first. * * === Parameters * * +size+ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. * * +generator+ is a small number > 1, typically 2 or 5. * * +string+ contains the DER or PEM encoded key. * * === Examples * DH.new # -> dh * DH.new(1024) # -> dh * DH.new(1024, 5) # -> dh * #Reading DH parameters * dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet * dh.generate_key! # -> dh with public and private key */ static VALUE ossl_dh_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; DH *dh; int g = 2; BIO *in; VALUE arg, gen; GetPKey(self, pkey); if(RB_SCAN_ARGS_02(argc, argv, "02", &arg, &gen) == 0) { dh = DH_new(); } else if (FIXNUM_P(arg)) { if (!NIL_P(gen)) { g = NUM2INT(gen); } if (!(dh = dh_generate(FIX2INT(arg), g))) { ossl_raise(eDHError, NULL); } } else { arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(arg); dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); if (!dh){ OSSL_BIO_reset(in); dh = d2i_DHparams_bio(in, NULL); } BIO_free(in); if (!dh) { ossl_raise(eDHError, NULL); } } if (!EVP_PKEY_assign_DH(pkey, dh)) { DH_free(dh); ossl_raise(eDHError, NULL); } return self; }
/* * call-seq: * Session.new(SSLSocket | string) => session * * === Parameters * +SSLSocket+ is an OpenSSL::SSL::SSLSocket * +string+ must be a DER or PEM encoded Session. */ static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1) { SSL_SESSION *ctx = NULL; if (RDATA(self)->data) ossl_raise(eSSLSession, "SSL Session already initialized"); if (rb_obj_is_instance_of(arg1, cSSLSocket)) { SSL *ssl; Data_Get_Struct(arg1, SSL, ssl); if (!ssl || (ctx = SSL_get1_session(ssl)) == NULL) ossl_raise(eSSLSession, "no session available"); } else { BIO *in = ossl_obj2bio(arg1); ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL); if (!ctx) { OSSL_BIO_reset(in); ctx = d2i_SSL_SESSION_bio(in, NULL); } BIO_free(in); if (!ctx) ossl_raise(rb_eArgError, "unknown type"); } /* should not happen */ if (ctx == NULL) ossl_raise(eSSLSession, "ctx not set - internal error"); RDATA(self)->data = ctx; return self; }
/* call-seq: * OpenSSL::PKey::EC.new() * OpenSSL::PKey::EC.new(ec_key) * OpenSSL::PKey::EC.new(ec_group) * OpenSSL::PKey::EC.new("secp112r1") * OpenSSL::PKey::EC.new(pem_string) * OpenSSL::PKey::EC.new(pem_string [, pwd]) * OpenSSL::PKey::EC.new(der_string) * * See the OpenSSL documentation for: * EC_KEY_* */ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; EC_KEY *ec = NULL; VALUE arg, pass; VALUE group = Qnil; char *passwd = NULL; GetPKey(self, pkey); if (pkey->pkey.ec) ossl_raise(eECError, "EC_KEY already initialized"); rb_scan_args(argc, argv, "02", &arg, &pass); if (NIL_P(arg)) { ec = EC_KEY_new(); } else { if (rb_obj_is_kind_of(arg, cEC)) { EC_KEY *other_ec = NULL; SafeRequire_EC_KEY(arg, other_ec); ec = EC_KEY_dup(other_ec); } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { ec = EC_KEY_new(); group = arg; } else { BIO *in = ossl_obj2bio(arg); if (!NIL_P(pass)) { passwd = StringValuePtr(pass); } ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); if (!ec) { OSSL_BIO_reset(in); ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd); } if (!ec) { OSSL_BIO_reset(in); ec = d2i_ECPrivateKey_bio(in, NULL); } if (!ec) { OSSL_BIO_reset(in); ec = d2i_EC_PUBKEY_bio(in, NULL); } BIO_free(in); if (ec == NULL) { const char *name = StringValueCStr(arg); int nid = OBJ_sn2nid(name); (void)ERR_get_error(); if (nid == NID_undef) ossl_raise(eECError, "unknown curve name (%s)\n", name); if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL) ossl_raise(eECError, "unable to create curve (%s)\n", name); EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); } } } if (ec == NULL) ossl_raise(eECError, NULL); if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { EC_KEY_free(ec); ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); } rb_iv_set(self, "@group", Qnil); if (!NIL_P(group)) rb_funcall(self, rb_intern("group="), 1, arg); return self; }