Example #1
0
static VALUE
ossl_x509crl_copy(VALUE self, SEL sel, VALUE other)
{
    X509_CRL *a, *b, *crl;

    rb_check_frozen(self);
    if (self == other) return self;
    GetX509CRL(self, a);
    SafeGetX509CRL(other, b);
    if (!(crl = X509_CRL_dup(b))) {
	ossl_raise(eX509CRLError, NULL);
    }
    X509_CRL_free(a);
    DATA_PTR(self) = crl;

    return self;
}
Example #2
0
/*
 *  call-seq:
 *     ssl.session_reused? -> true | false
 *
 */
static VALUE
ossl_ssl_session_reused(VALUE self)
{
    SSL *ssl;

    Data_Get_Struct(self, SSL, ssl);
    if (!ssl) {
        rb_warning("SSL session is not started yet.");
        return Qnil;
    }

    switch(SSL_session_reused(ssl)) {
    case 1:	return Qtrue;
    case 0:	return Qfalse;
    default:	ossl_raise(eSSLError, "SSL_session_reused");
    }
}
Example #3
0
/* Document-method: OpenSSL::Engine#ctrl_cmd
 *
 * call-seq:
 *    engine.ctrl_cmd(command, value = nil) -> engine
 *
 * Send the given +command+ to this engine.
 *
 * Raises an EngineError if the +command+ fails.
 */
static VALUE
ossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self)
{
    ENGINE *e;
    VALUE cmd, val;
    int ret;

    GetEngine(self, e);
    rb_scan_args(argc, argv, "11", &cmd, &val);
    StringValue(cmd);
    if (!NIL_P(val)) StringValue(val);
    ret = ENGINE_ctrl_cmd_string(e, RSTRING_PTR(cmd),
				 NIL_P(val) ? NULL : RSTRING_PTR(val), 0);
    if (!ret) ossl_raise(eEngineError, NULL);

    return self;
}
Example #4
0
/*
 * call-seq:
 *    PKCS12.create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]])
 *
 * === Parameters
 * * +pass+ - string
 * * +name+ - A string describing the key.
 * * +key+ - Any PKey.
 * * +cert+ - A X509::Certificate.
 * * * The public_key portion of the certificate must contain a valid public key.
 * * * The not_before and not_after fields must be filled in.
 * * +ca+ - An optional array of X509::Certificate's.
 * * +key_pbe+ - string
 * * +cert_pbe+ - string
 * * +key_iter+ - integer
 * * +mac_iter+ - integer
 * * +keytype+ - An integer representing an MSIE specific extension.
 *
 * Any optional arguments may be supplied as nil to preserve the OpenSSL defaults.
 *
 * See the OpenSSL documentation for PKCS12_create().
 */
static VALUE
ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
{
    VALUE pass, name, pkey, cert, ca, key_nid, cert_nid, key_iter, mac_iter, keytype;
    VALUE obj;
    char *passphrase, *friendlyname;
    EVP_PKEY *key;
    X509 *x509;
    STACK_OF(X509) *x509s;
    int nkey = 0, ncert = 0, kiter = 0, miter = 0, ktype = 0;
    PKCS12 *p12;
    
    rb_scan_args(argc, argv, "46", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype);
    passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
    friendlyname = NIL_P(name) ? NULL : StringValuePtr(name);
    key = GetPKeyPtr(pkey);
    x509 = GetX509CertPtr(cert);
    x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca);
/* TODO: make a VALUE to nid function */
    if (!NIL_P(key_nid)) {
        if ((nkey = OBJ_txt2nid(StringValuePtr(key_nid))) == NID_undef)
            rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(key_nid));
    }
    if (!NIL_P(cert_nid)) {
        if ((ncert = OBJ_txt2nid(StringValuePtr(cert_nid))) == NID_undef)
            rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(cert_nid));
    }
    if (!NIL_P(key_iter))
        kiter = NUM2INT(key_iter);
    if (!NIL_P(mac_iter))
        miter = NUM2INT(mac_iter);
    if (!NIL_P(keytype))
        ktype = NUM2INT(keytype);

    p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s,
                        nkey, ncert, kiter, miter, ktype);
    sk_X509_pop_free(x509s, X509_free);
    if(!p12) ossl_raise(ePKCS12Error, NULL);
    WrapPKCS12(cPKCS12, obj, p12);

    ossl_pkcs12_set_key(obj, pkey);
    ossl_pkcs12_set_cert(obj, cert);
    ossl_pkcs12_set_ca_certs(obj, ca);

    return obj;
}
Example #5
0
/*
 *  call-seq:
 *     dh.public_key -> aDH
 *
 * Returns a new DH instance that carries just the public information, i.e.
 * the prime +p+ and the generator +g+, but no public/private key yet. Such
 * a pair may be generated using DH#generate_key!. The "public key" needed
 * for a key exchange with DH#compute_key is considered as per-session
 * information and may be retrieved with DH#pub_key once a key pair has
 * been generated.
 * If the current instance already contains private information (and thus a
 * valid public/private key pair), this information will no longer be present
 * in the new instance generated by DH#public_key. This feature is helpful for
 * publishing the Diffie-Hellman parameters without leaking any of the private
 * per-session information.
 *
 * === Example
 *  dh = OpenSSL::PKey::DH.new(2048) # has public and private key set
 *  public_key = dh.public_key # contains only prime and generator
 *  parameters = public_key.to_der # it's safe to publish this
 */
static VALUE
ossl_dh_to_public_key(VALUE self)
{
    EVP_PKEY *pkey;
    DH *dh;
    VALUE obj;

    GetPKeyDH(self, pkey);
    dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */
    obj = dh_instance(CLASS_OF(self), dh);
    if (obj == Qfalse) {
	DH_free(dh);
	ossl_raise(eDHError, NULL);
    }

    return obj;
}
Example #6
0
static VALUE
ossl_bn_copy(VALUE self, VALUE other)
{
    BIGNUM *bn1, *bn2;
    
    rb_check_frozen(self);
    
    if (self == other) return self;
    
    GetBN(self, bn1);
    bn2 = GetBNPtr(other);
    
    if (!BN_copy(bn1, bn2)) {
	ossl_raise(eBNError, NULL);
    }
    return self;
}
Example #7
0
/*
 * call-seq:
 *    bn.to_i => integer
 */
static VALUE
ossl_bn_to_i(VALUE self)
{
    BIGNUM *bn;
    char *txt;
    VALUE num;

    GetBN(self, bn);

    if (!(txt = BN_bn2dec(bn))) {
	ossl_raise(eBNError, NULL);
    }
    num = rb_cstr_to_inum(txt, 10, Qtrue);
    OPENSSL_free(txt);

    return num;
}
/*
 *  call-seq:
 *     key.public_key   => OpenSSL::PKey::EC::Point
 *
 *  See the OpenSSL documentation for EC_KEY_get0_public_key()
 */
static VALUE ossl_ec_key_get_public_key(VALUE self)
{
    EC_KEY *ec;
    const EC_POINT *point;
    VALUE group;

    Require_EC_KEY(self, ec);

    if ((point = EC_KEY_get0_public_key(ec)) == NULL)
        return Qnil;

    group = rb_funcall(self, rb_intern("group"), 0);
    if (NIL_P(group))
        ossl_raise(eECError, "EC_KEY_get0_get0_group (has public_key but no group???");

    return ossl_ec_point_dup(point, group);
}
Example #9
0
static VALUE ossl_ec_point_dup(const EC_POINT *point, VALUE group_v)
{
    VALUE obj;
    const EC_GROUP *group;
    ossl_ec_point *new_point;

    obj = rb_obj_alloc(cEC_POINT);
    Data_Get_Struct(obj, ossl_ec_point, new_point);

    SafeRequire_EC_GROUP(group_v, group);

    new_point->point = EC_POINT_dup(point, group);
    if (new_point->point == NULL)
        ossl_raise(eEC_POINT, "EC_POINT_dup");
    rb_iv_set(obj, "@group", group_v);

    return obj;
}
Example #10
0
static VALUE
decode_enum(unsigned char* der, int length)
{
    ASN1_ENUMERATED *ai;
    const unsigned char *p;
    VALUE ret;
    int status = 0;

    p = der;
    if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length)))
	ossl_raise(eASN1Error, NULL);
    ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num,
		     (VALUE)ai, &status);
    ASN1_ENUMERATED_free(ai);
    if(status) rb_jump_tag(status);

    return ret;
}
Example #11
0
/*
 * call-seq:
 *    PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string
 *
 * === Parameters
 * * +pass+ - string
 * * +salt+ - string
 * * +iter+ - integer - should be greater than 1000.  2000 is better.
 * * +keylen+ - integer
 *
 * This method is available almost any version OpenSSL.
 *
 * Conforms to rfc2898.
 */
static VALUE
ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)
{
    VALUE str;
    int len = NUM2INT(keylen);

    StringValue(pass);
    StringValue(salt);

    str = rb_str_new(0, len);

    if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass),
			       (const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter),
			       len, (unsigned char *)RSTRING_PTR(str)) != 1)
        ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1");

    return str;
}
Example #12
0
static VALUE
decode_time(unsigned char* der, int length)
{
    ASN1_TIME *time;
    const unsigned char *p;
    VALUE ret;
    int status = 0;

    p = der;
    if(!(time = d2i_ASN1_TIME(NULL, &p, length)))
	ossl_raise(eASN1Error, NULL);
    ret = rb_protect((VALUE(*)_((VALUE)))asn1time_to_time,
		     (VALUE)time, &status);
    ASN1_TIME_free(time);
    if(status) rb_jump_tag(status);

    return ret;
}
Example #13
0
static VALUE
ossl_bn_coerce(VALUE self, VALUE other)
{
    switch(TYPE(other)) {
    case T_STRING:
	self = ossl_bn_to_s(0, NULL, self);
	break;
    case T_FIXNUM:
    case T_BIGNUM:
	self = ossl_bn_to_i(self);
	break;
    default:
	if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
	    ossl_raise(rb_eTypeError, "Don't know how to coerce");
	}
    }
    return rb_assoc_new(other, self);
}
Example #14
0
static VALUE
ossl_cipher_copy(VALUE self, VALUE other)
{
    EVP_CIPHER_CTX *ctx1, *ctx2;

    rb_check_frozen(self);
    if (self == other) return self;

    GetCipherInit(self, ctx1);
    if (!ctx1) {
	AllocCipher(self, ctx1);
    }
    SafeGetCipher(other, ctx2);
    if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1)
	ossl_raise(eCipherError, NULL);

    return self;
}
static VALUE
ossl_pkcs7si_initialize(VALUE self, VALUE cert, VALUE key, VALUE digest)
{
    PKCS7_SIGNER_INFO *p7si;
    EVP_PKEY *pkey;
    X509 *x509;
    const EVP_MD *md;

    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
    md = GetDigestPtr(digest);
    GetPKCS7si(self, p7si);
    if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, (EVP_MD*)md))) {
	ossl_raise(ePKCS7Error, NULL);
    }

    return self;
}
Example #16
0
static VALUE
ossl_ocspbres_get_status(VALUE self)
{
    OCSP_BASICRESP *bs;
    OCSP_SINGLERESP *single;
    OCSP_CERTID *cid;
    ASN1_TIME *revtime, *thisupd, *nextupd;
    int status, reason;
    X509_EXTENSION *x509ext;
    VALUE ret, ary, ext;
    int count, ext_count, i, j;

    GetOCSPBasicRes(self, bs);
    ret = rb_ary_new();
    count = OCSP_resp_count(bs);
    for(i = 0; i < count; i++) {
        single = OCSP_resp_get0(bs, i);
        if(!single) continue;

        revtime = thisupd = nextupd = NULL;
        status = OCSP_single_get0_status(single, &reason, &revtime,
                                         &thisupd, &nextupd);
        if(status < 0) continue;
        if(!(cid = OCSP_CERTID_dup(single->certId)))
            ossl_raise(eOCSPError, NULL);
        ary = rb_ary_new();
        rb_ary_push(ary, ossl_ocspcertid_new(cid));
        rb_ary_push(ary, INT2NUM(status));
        rb_ary_push(ary, INT2NUM(reason));
        rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil);
        rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil);
        rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil);
        ext = rb_ary_new();
        ext_count = OCSP_SINGLERESP_get_ext_count(single);
        for(j = 0; j < ext_count; j++) {
            x509ext = OCSP_SINGLERESP_get_ext(single, j);
            rb_ary_push(ext, ossl_x509ext_new(x509ext));
        }
        rb_ary_push(ary, ext);
        rb_ary_push(ret, ary);
    }

    return ret;
}
Example #17
0
/*
 *  call-seq:
 *     Digest.new(string [, data]) -> Digest
 *
 * Creates a Digest instance based on +string+, which is either the ln
 * (long name) or sn (short name) of a supported digest algorithm.
 * If +data+ (a +String+) is given, it is used as the initial input to the
 * Digest instance, i.e.
 *   digest = OpenSSL::Digest.new('sha256', 'digestdata')
 * is equal to
 *   digest = OpenSSL::Digest.new('sha256')
 *   digest.update('digestdata')
 *
 * === Example
 *   digest = OpenSSL::Digest.new('sha1')
 *
 *
 */
static VALUE
ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_MD_CTX *ctx;
    const EVP_MD *md;
    VALUE type, data;

    rb_scan_args(argc, argv, "11", &type, &data);
    md = GetDigestPtr(type);
    if (!NIL_P(data)) StringValue(data);

    GetDigest(self, ctx);
    if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
	ossl_raise(eDigestError, "Digest initialization failed.");
    }

    if (!NIL_P(data)) return ossl_digest_update(self, data);
    return self;
}
Example #18
0
static VALUE
ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
{
    EVP_CIPHER_CTX *ctx;
    unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL;
    unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL;
    VALUE pass, init_v;

    if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){
	/*
	 * oops. this code mistakes salt for IV.
	 * We deprecated the arguments for this method, but we decided
	 * keeping this behaviour for backward compatibility.
	 */
	VALUE cname  = rb_class_path(rb_obj_class(self));
	rb_warn("arguments for %"PRIsVALUE"#encrypt and %"PRIsVALUE"#decrypt were deprecated; "
                "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV",
                cname, cname, cname);
	StringValue(pass);
	GetCipher(self, ctx);
	if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv));
	else{
	    StringValue(init_v);
	    if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) {
		memset(iv, 0, EVP_MAX_IV_LENGTH);
		memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v));
	    }
	    else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv));
	}
	EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv,
		       (unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL);
	p_key = key;
	p_iv = iv;
    }
    else {
	GetCipher(self, ctx);
    }
    if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) {
	ossl_raise(eCipherError, NULL);
    }

    return self;
}
Example #19
0
static VALUE
ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE arg;
    unsigned char *p;

    rb_scan_args(argc, argv, "01", &arg);
    if(!NIL_P(arg)) {
        arg = ossl_to_der_if_possible(arg);
        StringValue(arg);
        p = RSTRING_PTR(arg);
        if(!d2i_OCSP_RESPONSE((OCSP_RESPONSE**)&DATA_PTR(self), &p,
                              RSTRING_LEN(arg))) {
            ossl_raise(eOCSPError, "cannot load DER encoded response");
        }
    }

    return self;
}
Example #20
0
/*
 * call-seq:
 *    session.to_der -> aString
 *
 * Returns an ASN1 encoded String that contains the Session object.
*/
static VALUE ossl_ssl_session_to_der(VALUE self)
{
	SSL_SESSION *ctx;
	unsigned char *p;
	int len;
	VALUE str;

	GetSSLSession(self, ctx);
	len = i2d_SSL_SESSION(ctx, NULL);
	if (len <= 0) {
		ossl_raise(eSSLSession, "i2d_SSL_SESSION");
	}

	str = rb_str_new(0, len);
	p = (unsigned char *)RSTRING_PTR(str);
	i2d_SSL_SESSION(ctx, &p);
	ossl_str_adjust(str, p);
	return str;
}
Example #21
0
/*
 *  call-seq:
 *     DH.generate(size [, generator]) -> dh
 *
 * Creates a new DH instance from scratch by generating the private and public
 * components alike.
 *
 * === 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.
 *
 */
static VALUE
ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
{
    DH *dh ;
    int g = 2;
    VALUE size, gen, obj;

    if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) {
	g = NUM2INT(gen);
    }
    dh = dh_generate(NUM2INT(size), g);
    obj = dh_instance(klass, dh);
    if (obj == Qfalse) {
	DH_free(dh);
	ossl_raise(eDHError, NULL);
    }

    return obj;
}
Example #22
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;
}
Example #23
0
/*
 *  call-seq:
 *     cipher.auth_data = string -> string
 *
 *  Sets the cipher's additional authenticated data. This field must be
 *  set when using AEAD cipher modes such as GCM or CCM. If no associated
 *  data shall be used, this method must *still* be called with a value of "".
 *  The contents of this field should be non-sensitive data which will be
 *  added to the ciphertext to generate the authentication tag which validates
 *  the contents of the ciphertext.
 *
 *  The AAD must be set prior to encryption or decryption. In encryption mode,
 *  it must be set after calling Cipher#encrypt and setting Cipher#key= and
 *  Cipher#iv=. When decrypting, the authenticated data must be set after key,
 *  iv and especially *after* the authentication tag has been set. I.e. set it
 *  only after calling Cipher#decrypt, Cipher#key=, Cipher#iv= and
 *  Cipher#auth_tag= first.
 */
static VALUE
ossl_cipher_set_auth_data(VALUE self, VALUE data)
{
    EVP_CIPHER_CTX *ctx;
    unsigned char *in;
    long in_len, out_len;

    StringValue(data);

    in = (unsigned char *) RSTRING_PTR(data);
    in_len = RSTRING_LEN(data);

    GetCipher(self, ctx);

    if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len))
        ossl_raise(eCipherError, "couldn't set additional authenticated data");

    return data;
}
static VALUE
ossl_pkcs7_add_signer(VALUE self, VALUE signer)
{
    PKCS7 *pkcs7;
    PKCS7_SIGNER_INFO *p7si;

    p7si = DupPKCS7SignerPtr(signer); /* NEED TO DUP */
    GetPKCS7(self, pkcs7);
    if (!PKCS7_add_signer(pkcs7, p7si)) {
	PKCS7_SIGNER_INFO_free(p7si);
	ossl_raise(ePKCS7Error, "Could not add signer.");
    }
    if (PKCS7_type_is_signed(pkcs7)){
	PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
				   V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
    }

    return self;
}
/*
 * 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;
}
static VALUE
ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
{
    EVP_CIPHER_CTX *ctx;
    unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL;
    unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL;
    VALUE pass, init_v;

    if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){
	/*
	 * oops. this code mistakes salt for IV.
	 * We deprecated the arguments for this method, but we decided
	 * keeping this behaviour for backward compatibility.
	 */
	StringValue(pass);
	GetCipher(self, ctx);
	if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv));
	else{
	    char *cname  = rb_class2name(rb_obj_class(self));
	    rb_warning("key derivation by %s#encrypt is deprecated; "
		       "use %s::pkcs5_keyivgen instead", cname, cname);
	    StringValue(init_v);
	    if (EVP_MAX_IV_LENGTH > RSTRING(init_v)->len) {
		memset(iv, 0, EVP_MAX_IV_LENGTH);
		memcpy(iv, RSTRING(init_v)->ptr, RSTRING(init_v)->len);
	    }
	    else memcpy(iv, RSTRING(init_v)->ptr, sizeof(iv));
	}
	EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv,
		       RSTRING(pass)->ptr, RSTRING(pass)->len, 1, key, NULL);
	p_key = key;
	p_iv = iv;
    }
    else {
	GetCipher(self, ctx);
    }
    if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) {
	ossl_raise(eCipherError, NULL);
    }

    return self;
}
Example #27
0
/*
 * call-seq:
 *   OpenSSL.print_mem_leaks -> true | false
 *
 * For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr).
 * Prints detected memory leaks to standard error. This cleans the global state
 * up thus you cannot use any methods of the library after calling this.
 *
 * Returns +true+ if leaks detected, +false+ otherwise.
 *
 * This is available only when built with a capable OpenSSL and --enable-debug
 * configure option.
 *
 * === Example
 *   OpenSSL.mem_check_start
 *   NOT_GCED = OpenSSL::PKey::RSA.new(256)
 *
 *   END {
 *     GC.start
 *     OpenSSL.print_mem_leaks # will print the leakage
 *   }
 */
static VALUE
print_mem_leaks(VALUE self)
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000
    int ret;
#endif

    BN_CTX_free(ossl_bn_ctx);
    ossl_bn_ctx = NULL;

#if OPENSSL_VERSION_NUMBER >= 0x10100000
    ret = CRYPTO_mem_leaks_fp(stderr);
    if (ret < 0)
	ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp");
    return ret ? Qfalse : Qtrue;
#else
    CRYPTO_mem_leaks_fp(stderr);
    return Qnil;
#endif
}
Example #28
0
static int
ossl_asn1_is_explicit(VALUE obj)
{
    VALUE s;
    int ret = -1;

    s = ossl_asn1_get_tagging(obj);
    if(NIL_P(s)) return 0;
    else if(SYMBOL_P(s)){
	if (SYM2ID(s) == sIMPLICIT)
	    ret = 0;
	else if (SYM2ID(s) == sEXPLICIT)
	    ret = 1;
    }
    if(ret < 0){
	ossl_raise(eASN1Error, "invalid tag default");
    }

    return ret;
}
Example #29
0
static VALUE
decode_bstr(unsigned char* der, int length, long *unused_bits)
{
    ASN1_BIT_STRING *bstr;
    const unsigned char *p;
    long len;
    VALUE ret;

    p = der;
    if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
	ossl_raise(eASN1Error, NULL);
    len = bstr->length;
    *unused_bits = 0;
    if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
	*unused_bits = bstr->flags & 0x07;
    ret = rb_str_new((const char *)bstr->data, len);
    ASN1_BIT_STRING_free(bstr);

    return ret;
}
static VALUE
ossl_pkcs7_copy(VALUE self, VALUE other)
{
    PKCS7 *a, *b, *pkcs7;

    rb_check_frozen(self);
    if (self == other) return self;

    GetPKCS7(self, a);
    SafeGetPKCS7(other, b);

    pkcs7 = PKCS7_dup(b);
    if (!pkcs7) {
	ossl_raise(ePKCS7Error, NULL);
    }
    DATA_PTR(self) = pkcs7;
    PKCS7_free(a);

    return self;
}