static VALUE
ossl_pkcs7_add_data(VALUE self, VALUE data)
{
    PKCS7 *pkcs7;
    BIO *out, *in;
    char buf[4096];
    int len;

    in = ossl_obj2bio(data);
    GetPKCS7(self, pkcs7);
    if(PKCS7_type_is_signed(pkcs7)){
	if(!PKCS7_content_new(pkcs7, NID_pkcs7_data))
	    ossl_raise(ePKCS7Error, NULL);
    }
    if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err;
    for(;;){
	if((len = BIO_read(in, buf, sizeof(buf))) <= 0)
	    break;
	if(BIO_write(out, buf, len) != len)
	    goto err;
    }
    if(!PKCS7_dataFinal(pkcs7, out)) goto err;
    ossl_pkcs7_set_data(self, Qnil);

 err:
    BIO_free(out);
    BIO_free(in);
    if(ERR_peek_error()){
	ossl_raise(ePKCS7Error, NULL);
    }

    return data;
}
/*
 * 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;
}
Example #3
0
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;
}
Example #4
0
/*
 * GetConfigPtr is a public C-level function for getting OpenSSL CONF struct
 * from an OpenSSL::Config(eConfig) instance.  We decided to implement
 * OpenSSL::Config in Ruby level but we need to pass native CONF struct for
 * some OpenSSL features such as X509V3_EXT_*.
 */
CONF *
GetConfigPtr(VALUE obj)
{
    CONF *conf;
    VALUE str;
    BIO *bio;
    long eline = -1;

    OSSL_Check_Kind(obj, cConfig);
    str = rb_funcall(obj, rb_intern("to_s"), 0);
    bio = ossl_obj2bio(str);
    conf = NCONF_new(NULL);
    if(!conf) {
        BIO_free(bio);
        ossl_raise(eConfigError, NULL);
    }
    if(!NCONF_load_bio(conf, bio, &eline)) {
        BIO_free(bio);
        NCONF_free(conf);
        if (eline <= 0) ossl_raise(eConfigError, "wrong config format");
        else ossl_raise(eConfigError, "error in line %d", eline);
        ossl_raise(eConfigError, NULL);
    }
    BIO_free(bio);

    return conf;
}
Example #5
0
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;
}
Example #6
0
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:
 *    PKCS7.write_smime(pkcs7 [, data [, flags]]) => string
 */
static VALUE
ossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass)
{
    VALUE pkcs7, data, flags;
    BIO *out, *in;
    PKCS7 *p7;
    VALUE str;
    int flg;

    rb_scan_args(argc, argv, "12", &pkcs7, &data, &flags);
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    if(NIL_P(data)) data = ossl_pkcs7_get_data(pkcs7);
    SafeGetPKCS7(pkcs7, p7);
    if(!NIL_P(data) && PKCS7_is_detached(p7))
	flg |= PKCS7_DETACHED;
    in = NIL_P(data) ? NULL : ossl_obj2bio(data);
    if(!(out = BIO_new(BIO_s_mem()))){
        BIO_free(in);
        ossl_raise(ePKCS7Error, NULL);
    }
    if(!SMIME_write_PKCS7(out, p7, in, flg)){
        BIO_free(out);
        BIO_free(in);
        ossl_raise(ePKCS7Error, NULL);
    }
    BIO_free(in);
    str = ossl_membio2str(out);

    return str;
}
Example #8
0
/*
 *  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);
}
Example #9
0
/*  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;
}
Example #10
0
static VALUE
ossl_cms_verify(int argc, VALUE *argv, VALUE self)
{
    VALUE certs, store, indata, flags;
    STACK_OF(X509) *x509s;
    X509_STORE *x509st;
    int flg, ok, status = 0;
    BIO *in, *out;
    CMS_ContentInfo *cms;
    VALUE data;
    const char *msg;

    rb_scan_args(argc, argv, "22", &certs, &store, &indata, &flags);
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);

    if(NIL_P(indata)) indata = ossl_cms_get_data(self);
    in = NIL_P(indata) ? NULL : ossl_obj2bio(indata);

    if(NIL_P(certs)) x509s = NULL;
    else{
        x509s = ossl_protect_x509_ary2sk(certs, &status);
        if(status){
            BIO_free(in);
            rb_jump_tag(status);
        }
    }

    x509st = GetX509StorePtr(store);
    GetCMS(self, cms);

    if(!(out = BIO_new(BIO_s_mem()))){
        BIO_free(in);
        sk_X509_pop_free(x509s, X509_free);
        ossl_raise(eCMSError, NULL);
    }

    ok = CMS_verify(cms, x509s, x509st, in, out, flg);

    BIO_free(in);
    if (ok < 0) ossl_raise(eCMSError, NULL);

    msg = ERR_reason_error_string(ERR_get_error());
    ossl_cms_set_err_string(self, msg ? rb_str_new2(msg) : Qnil);
    ERR_clear_error();

    data = ossl_membio2str(out);

    ossl_cms_set_data(self, data);
    sk_X509_pop_free(x509s, X509_free);

    return (ok == 1) ? Qtrue : Qfalse;
}
Example #11
0
/*
 * call-seq:
 *    PKCS7.encrypt(certs, data, [, cipher [, flags]]) => pkcs7
 */
static VALUE
ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)
{
    VALUE certs, data, cipher, flags;
    STACK_OF(X509) *x509s;
    BIO *in;
    const EVP_CIPHER *ciph;
    int flg, status = 0;
    VALUE ret;
    PKCS7 *p7;

    rb_scan_args(argc, argv, "22", &certs, &data, &cipher, &flags);
    if(NIL_P(cipher)){
#if !defined(OPENSSL_NO_RC2)
	ciph = EVP_rc2_40_cbc();
#elif !defined(OPENSSL_NO_DES)
	ciph = EVP_des_ede3_cbc();
#elif !defined(OPENSSL_NO_RC2)
	ciph = EVP_rc2_40_cbc();
#elif !defined(OPENSSL_NO_AES)
	ciph = EVP_EVP_aes_128_cbc();
#else
	ossl_raise(ePKCS7Error, "Must specify cipher");
#endif

    }
    else ciph = GetCipherPtr(cipher); /* NO NEED TO DUP */
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    ret = NewPKCS7(cPKCS7);
    in = ossl_obj2bio(data);
    x509s = ossl_protect_x509_ary2sk(certs, &status);
    if(status){
	BIO_free(in);
	rb_jump_tag(status);
    }
    if(!(p7 = PKCS7_encrypt(x509s, in, (EVP_CIPHER*)ciph, flg))){
	BIO_free(in);
	sk_X509_pop_free(x509s, X509_free);
	ossl_raise(ePKCS7Error, NULL);
    }
    BIO_free(in);
    SetPKCS7(ret, p7);
    ossl_pkcs7_set_data(ret, data);
    sk_X509_pop_free(x509s, X509_free);

    return ret;
}
/*
 * call-seq:
 *    PKCS7.read_smime(string) => pkcs7
 */
static VALUE
ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg)
{
    BIO *in, *out;
    PKCS7 *pkcs7;
    VALUE ret, data;

    in = ossl_obj2bio(arg);
    out = NULL;
    pkcs7 = SMIME_read_PKCS7(in, &out);
    BIO_free(in);
    if(!pkcs7) ossl_raise(ePKCS7Error, NULL);
    data = out ? ossl_membio2str(out) : Qnil;
    WrapPKCS7(cPKCS7, ret, pkcs7);
    ossl_pkcs7_set_data(ret, data);
    ossl_pkcs7_set_err_string(ret, Qnil);

    return ret;
}
Example #13
0
/*
 * call-seq:
 *    PKCS12.new -> pkcs12
 *    PKCS12.new(str) -> pkcs12
 *    PKCS12.new(str, pass) -> pkcs12
 *
 * === Parameters
 * * +str+ - Must be a DER encoded PKCS12 string.
 * * +pass+ - string
 */
static VALUE
ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
{
    BIO *in;
    VALUE arg, pass, pkey, cert, ca;
    char *passphrase;
    EVP_PKEY *key;
    X509 *x509;
    STACK_OF(X509) *x509s = NULL;
    int st = 0;
    PKCS12 *pkcs = DATA_PTR(self);

    if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self;
    passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
    in = ossl_obj2bio(arg);
    d2i_PKCS12_bio(in, &pkcs);
    DATA_PTR(self) = pkcs;
    BIO_free(in);

    pkey = cert = ca = Qnil;
    if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
	ossl_raise(ePKCS12Error, "PKCS12_parse");
    pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key,
		      &st); /* NO DUP */
    if(st) goto err;
    cert = rb_protect((VALUE(*)_((VALUE)))ossl_x509_new, (VALUE)x509, &st);
    if(st) goto err;
    if(x509s){
	ca =
	    rb_protect((VALUE(*)_((VALUE)))ossl_x509_sk2ary, (VALUE)x509s, &st);
	if(st) goto err;
    }

  err:
    X509_free(x509);
    sk_X509_pop_free(x509s, X509_free);
    ossl_pkcs12_set_key(self, pkey);
    ossl_pkcs12_set_cert(self, cert);
    ossl_pkcs12_set_ca_certs(self, ca);
    if(st) rb_jump_tag(st);

    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;
	VALUE obj;
	unsigned char *p;

	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 ((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) {
			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;
}
Example #15
0
/*
 *  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;
}
Example #16
0
/*
 * 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;
    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, (PKCS7 **)&DATA_PTR(self), NULL, NULL);
    if (!p7) {
	BIO_reset(in);
        p7 = d2i_PKCS7_bio(in, (PKCS7 **)&DATA_PTR(self));
    }
    BIO_free(in);
    ossl_pkcs7_set_data(self, Qnil);
    ossl_pkcs7_set_err_string(self, Qnil);

    return self;
}
Example #17
0
/*
 * call-seq:
 *    PKCS7.sign(cert, key, data, [, certs [, flags]]) => pkcs7
 */
static VALUE
ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass)
{
    VALUE cert, key, data, certs, flags;
    X509 *x509;
    EVP_PKEY *pkey;
    BIO *in;
    STACK_OF(X509) *x509s;
    int flg, status = 0;
    PKCS7 *pkcs7;
    VALUE ret;

    rb_scan_args(argc, argv, "32", &cert, &key, &data, &certs, &flags);
    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    ret = NewPKCS7(cPKCS7);
    in = ossl_obj2bio(data);
    if(NIL_P(certs)) x509s = NULL;
    else{
	x509s = ossl_protect_x509_ary2sk(certs, &status);
	if(status){
	    BIO_free(in);
	    rb_jump_tag(status);
	}
    }
    if(!(pkcs7 = PKCS7_sign(x509, pkey, x509s, in, flg))){
	BIO_free(in);
	sk_X509_pop_free(x509s, X509_free);
	ossl_raise(ePKCS7Error, NULL);
    }
    SetPKCS7(ret, pkcs7);
    ossl_pkcs7_set_data(ret, data);
    ossl_pkcs7_set_err_string(ret, Qnil);
    BIO_free(in);
    sk_X509_pop_free(x509s, X509_free);

    return ret;
}
Example #18
0
static VALUE 
ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
{
    BIO *in;
    X509_CRL *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, (X509_CRL **)&DATA_PTR(self), NULL, NULL);
    if (!crl) {
	BIO_reset(in);
	crl = d2i_X509_CRL_bio(in, (X509_CRL **)&DATA_PTR(self));
    }
    BIO_free(in);
    if (!crl) ossl_raise(eX509CRLError, NULL);

    return self;
}
Example #19
0
/*
 * Private
 */
static CONF *
parse_config(VALUE str, CONF *dst)
{
    CONF *conf;
    BIO *bio;
    long eline = -1;

    bio = ossl_obj2bio(str);
    conf = dst ? dst : NCONF_new(NULL);
    if(!conf){
	BIO_free(bio);
	ossl_raise(eConfigError, NULL);
    }
    if(!NCONF_load_bio(conf, bio, &eline)){
	BIO_free(bio);
	if(!dst) NCONF_free(conf);
	if (eline <= 0) ossl_raise(eConfigError, "wrong config format");
	else ossl_raise(eConfigError, "error in line %d", eline);
	ossl_raise(eConfigError, NULL);
    }
    BIO_free(bio);

    return conf;
}
Example #20
0
/*  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)
        rb_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) {
                (void)BIO_reset(in);
                (void)ERR_get_error();
		ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd);
            }
            if (!ec) {
                (void)BIO_reset(in);
                (void)ERR_get_error();
                ec = d2i_ECPrivateKey_bio(in, NULL);
            }
            if (!ec) {
                (void)BIO_reset(in);
                (void)ERR_get_error();
                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;
}