Ejemplo n.º 1
0
static VALUE
ossl_asn1data_to_der(VALUE self)
{
    VALUE value, der, inf_length;
    int tag, tag_class, is_cons = 0, tmp_cons = 1;
    long length;
    unsigned char *p;

    value = ossl_asn1_get_value(self);
    if(rb_obj_is_kind_of(value, rb_cArray)){
	is_cons = 1;
	value = join_der(value);
    }
    StringValue(value);

    tag = ossl_asn1_tag(self);
    tag_class = ossl_asn1_tag_class(self);
    inf_length = ossl_asn1_get_infinite_length(self);
    if (inf_length == Qtrue) {
        is_cons = 2;
        tmp_cons = 2;
    }
    if((length = ASN1_object_size(tmp_cons, RSTRING_LENINT(value), tag)) <= 0)
	ossl_raise(eASN1Error, NULL);
    der = rb_str_new(0, length);
    p = (unsigned char *)RSTRING_PTR(der);
    ASN1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class);
    memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
    p += RSTRING_LEN(value);
    ossl_str_adjust(der, p);

    return der;
}
Ejemplo n.º 2
0
/*
 * call-seq:
 *   basicsocket.send(mesg, flags [, dest_sockaddr]) => numbytes_sent
 *
 * send _mesg_ via _basicsocket_.
 *
 * _mesg_ should be a string.
 *
 * _flags_ should be a bitwise OR of Socket::MSG_* constants.
 *
 * _dest_sockaddr_ should be a packed sockaddr string or an addrinfo.
 *
 *   TCPSocket.open("localhost", 80) {|s|
 *     s.send "GET / HTTP/1.0\r\n\r\n", 0
 *     p s.read
 *   }
 */
VALUE
rsock_bsock_send(int argc, VALUE *argv, VALUE sock)
{
    struct rsock_send_arg arg;
    VALUE flags, to;
    rb_io_t *fptr;
    int n;
    rb_blocking_function_t *func;

    rb_secure(4);
    rb_scan_args(argc, argv, "21", &arg.mesg, &flags, &to);

    StringValue(arg.mesg);
    if (!NIL_P(to)) {
	SockAddrStringValue(to);
	to = rb_str_new4(to);
	arg.to = (struct sockaddr *)RSTRING_PTR(to);
	arg.tolen = (socklen_t)RSTRING_LENINT(to);
	func = rsock_sendto_blocking;
    }
    else {
	func = rsock_send_blocking;
    }
    GetOpenFile(sock, fptr);
    arg.fd = fptr->fd;
    arg.flags = NUM2INT(flags);
    while (rb_thread_fd_writable(arg.fd),
	   (n = (int)BLOCKING_REGION_FD(func, &arg)) < 0) {
	if (rb_io_wait_writable(arg.fd)) {
	    continue;
	}
	rb_sys_fail("send(2)");
    }
    return INT2FIX(n);
}
Ejemplo n.º 3
0
BIO *
ossl_obj2bio(VALUE obj)
{
    BIO *bio;

    if (RB_TYPE_P(obj, T_FILE)) {
	rb_io_t *fptr;
	FILE *fp;
	int fd;

	GetOpenFile(obj, fptr);
	rb_io_check_readable(fptr);
	if ((fd = rb_cloexec_dup(FPTR_TO_FD(fptr))) < 0){
	    rb_sys_fail(0);
	}
        rb_update_max_fd(fd);
	if (!(fp = fdopen(fd, "r"))){
	    int e = errno;
	    close(fd);
	    rb_syserr_fail(e, 0);
	}
	if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){
	    fclose(fp);
	    ossl_raise(eOSSLError, NULL);
	}
    }
    else {
	StringValue(obj);
	bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj));
	if (!bio) ossl_raise(eOSSLError, NULL);
    }

    return bio;
}
Ejemplo n.º 4
0
Archivo: ossl.c Proyecto: fi8on/ruby
int
ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
{
    int len, status = 0;
    VALUE rflag, pass;

    if (pwd || !rb_block_given_p())
	return PEM_def_callback(buf, max_len, flag, pwd);

    while (1) {
	/*
	 * when the flag is nonzero, this passphrase
	 * will be used to perform encryption; otherwise it will
	 * be used to perform decryption.
	 */
	rflag = flag ? Qtrue : Qfalse;
	pass  = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
	if (status) return -1; /* exception was raised. */
	len = RSTRING_LENINT(pass);
	if (len < 4) { /* 4 is OpenSSL hardcoded limit */
	    rb_warning("password must be longer than 4 bytes");
	    continue;
	}
	if (len > max_len) {
	    rb_warning("password must be shorter then %d bytes", max_len-1);
	    continue;
	}
	memcpy(buf, RSTRING_PTR(pass), len);
	break;
    }
    return len;
}
Ejemplo n.º 5
0
/*
 *  call-seq:
 *     cipher.update(data [, buffer]) -> string or buffer
 *
 *  Encrypts data in a streaming fashion. Hand consecutive blocks of data
 *  to the +update+ method in order to encrypt it. Returns the encrypted
 *  data chunk. When done, the output of Cipher#final should be additionally
 *  added to the result.
 *
 *  === Parameters
 *  +data+ is a nonempty string.
 *  +buffer+ is an optional string to store the result.
 */
static VALUE
ossl_cipher_update(int argc, VALUE *argv, VALUE self)
{
    EVP_CIPHER_CTX *ctx;
    unsigned char *in;
    int in_len, out_len;
    VALUE data, str;

    rb_scan_args(argc, argv, "11", &data, &str);

    StringValue(data);
    in = (unsigned char *)RSTRING_PTR(data);
    if ((in_len = RSTRING_LENINT(data)) == 0)
        ossl_raise(rb_eArgError, "data must not be empty");
    GetCipher(self, ctx);
    out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);

    if (NIL_P(str)) {
        str = rb_str_new(0, out_len);
    } else {
        StringValue(str);
        rb_str_resize(str, out_len);
    }

    if (!EVP_CipherUpdate(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len))
	ossl_raise(eCipherError, NULL);
    assert(out_len < RSTRING_LEN(str));
    rb_str_set_len(str, out_len);

    return str;
}
Ejemplo n.º 6
0
/*
 *  call-seq:
 *     cipher.pkcs5_keyivgen(pass [, salt [, iterations [, digest]]] ) -> nil
 *
 *  Generates and sets the key/IV based on a password.
 *
 *  WARNING: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40,
 *  or DES with MD5 or SHA1. Using anything else (like AES) will generate the
 *  key/iv using an OpenSSL specific method. This method is deprecated and
 *  should no longer be used. Use a PKCS5 v2 key generation method from
 *  OpenSSL::PKCS5 instead.
 *
 *  === Parameters
 *  +salt+ must be an 8 byte string if provided.
 *  +iterations+ is a integer with a default of 2048.
 *  +digest+ is a Digest object that defaults to 'MD5'
 *
 *  A minimum of 1000 iterations is recommended.
 *
 */
static VALUE
ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
{
    EVP_CIPHER_CTX *ctx;
    const EVP_MD *digest;
    VALUE vpass, vsalt, viter, vdigest;
    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL;
    int iter;

    rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest);
    StringValue(vpass);
    if(!NIL_P(vsalt)){
	StringValue(vsalt);
	if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN)
	    ossl_raise(eCipherError, "salt must be an 8-octet string");
	salt = (unsigned char *)RSTRING_PTR(vsalt);
    }
    iter = NIL_P(viter) ? 2048 : NUM2INT(viter);
    digest = NIL_P(vdigest) ? EVP_md5() : GetDigestPtr(vdigest);
    GetCipher(self, ctx);
    EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
		   (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv);
    if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1)
	ossl_raise(eCipherError, NULL);
    OPENSSL_cleanse(key, sizeof key);
    OPENSSL_cleanse(iv, sizeof iv);

    return Qnil;
}
static VALUE t_set_sock_opt (VALUE self, VALUE signature, VALUE lev, VALUE optname, VALUE optval)
{
    int fd = evma_get_file_descriptor (NUM2ULONG (signature));
    int level = NUM2INT(lev), option = NUM2INT(optname);
    int i;
    const void *v;
    socklen_t len;

    switch (TYPE(optval)) {
    case T_FIXNUM:
        i = FIX2INT(optval);
        goto numval;
    case T_FALSE:
        i = 0;
        goto numval;
    case T_TRUE:
        i = 1;
numval:
        v = (void*)&i;
        len = sizeof(i);
        break;
    default:
        StringValue(optval);
        v = RSTRING_PTR(optval);
        len = RSTRING_LENINT(optval);
        break;
    }


    if (setsockopt(fd, level, option, (char *)v, len) < 0)
        rb_sys_fail("setsockopt");

    return INT2FIX(0);
}
Ejemplo n.º 8
0
/*
 *  call-seq:
 *     add(str, entropy) -> self
 *
 * Mixes the bytes from +str+ into the Pseudo Random Number Generator(PRNG)
 * state.
 *
 * Thus, if the data from +str+ are unpredictable to an adversary, this
 * increases the uncertainty about the state and makes the PRNG output less
 * predictable.
 *
 * The +entropy+ argument is (the lower bound of) an estimate of how much
 * randomness is contained in +str+, measured in bytes.
 *
 *  Example:
 *
 *    pid = $$
 *    now = Time.now
 *    ary = [now.to_i, now.nsec, 1000, pid]
 *    OpenSSL::Random.add(ary.join("").to_s, 0.0)
 *    OpenSSL::Random.seed(ary.join("").to_s)
 */
static VALUE
ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
{
    StringValue(str);
    RAND_add(RSTRING_PTR(str), RSTRING_LENINT(str), NUM2DBL(entropy));

    return self;
}
Ejemplo n.º 9
0
/*
 *  call-seq:
 *     seed(str) -> str
 *
 * ::seed is equivalent to ::add where +entropy+ is length of +str+.
 */
static VALUE
ossl_rand_seed(VALUE self, VALUE str)
{
    StringValue(str);
    RAND_seed(RSTRING_PTR(str), RSTRING_LENINT(str));

    return str;
}
Ejemplo n.º 10
0
static VALUE gl_LoadProgramNV(VALUE obj,VALUE arg1,VALUE arg2,VALUE arg3)
{
	LOAD_GL_FUNC(glLoadProgramNV, "GL_NV_vertex_program");
	Check_Type(arg3,T_STRING);
	fptr_glLoadProgramNV((GLenum)NUM2INT(arg1),(GLuint)NUM2UINT(arg2),(GLsizei)RSTRING_LENINT(arg3),(GLubyte *)RSTRING_PTR(arg3));
	CHECK_GLERROR_FROM("glLoadProgramNV");
	return Qnil;
}
Ejemplo n.º 11
0
static VALUE gl_ProgramStringARB(VALUE obj,VALUE arg1,VALUE arg2,VALUE arg3)
{
	LOAD_GL_FUNC(glProgramStringARB, "GL_ARB_vertex_program");
	Check_Type(arg3,T_STRING);
	fptr_glProgramStringARB((GLenum)NUM2INT(arg1),(GLenum)NUM2INT(arg2),(GLsizei)RSTRING_LENINT(arg3),RSTRING_PTR(arg3));
	CHECK_GLERROR_FROM("glProgramStringARB");
	return Qnil;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
static VALUE method_deserialize(VALUE self, VALUE bson) {
    const char* buffer = RSTRING_PTR(bson);
    int remaining = RSTRING_LENINT(bson);

    // NOTE we just swallow the size and end byte here
    buffer += 4;
    remaining -= 5;

    return elements_to_hash(buffer, remaining);
}
Ejemplo n.º 14
0
/*
 * call-seq:
 *    PKCS5.pbkdf2_hmac(pass, salt, iter, keylen, digest) => string
 *
 * === Parameters
 * * +pass+ - string
 * * +salt+ - string - should be at least 8 bytes long.
 * * +iter+ - integer - should be greater than 1000.  20000 is better.
 * * +keylen+ - integer
 * * +digest+ - a string or OpenSSL::Digest object.
 *
 * Available in OpenSSL 0.9.4.
 *
 * Digests other than SHA1 may not be supported by other cryptography libraries.
 */
static VALUE
ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest)
{
    VALUE str;
    const EVP_MD *md;
    int len = NUM2INT(keylen);

    StringValue(pass);
    StringValue(salt);
    md = GetDigestPtr(digest);

    str = rb_str_new(0, len);

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

    return str;
}
Ejemplo n.º 15
0
/*
 * Document-method: setsockopt
 * call-seq:
 *   setsockopt(level, optname, optval)
 *   setsockopt(socketoption)
 *
 * Sets a socket option. These are protocol and system specific, see your
 * local system documentation for details.
 *
 * === Parameters
 * * +level+ is an integer, usually one of the SOL_ constants such as
 *   Socket::SOL_SOCKET, or a protocol level.
 *   A string or symbol of the name, possibly without prefix, is also
 *   accepted.
 * * +optname+ is an integer, usually one of the SO_ constants, such
 *   as Socket::SO_REUSEADDR.
 *   A string or symbol of the name, possibly without prefix, is also
 *   accepted.
 * * +optval+ is the value of the option, it is passed to the underlying
 *   setsockopt() as a pointer to a certain number of bytes. How this is
 *   done depends on the type:
 *   - Fixnum: value is assigned to an int, and a pointer to the int is
 *     passed, with length of sizeof(int).
 *   - true or false: 1 or 0 (respectively) is assigned to an int, and the
 *     int is passed as for a Fixnum. Note that +false+ must be passed,
 *     not +nil+.
 *   - String: the string's data and length is passed to the socket.
 * * +socketoption+ is an instance of Socket::Option
 *
 * === Examples
 *
 * Some socket options are integers with boolean values, in this case
 * #setsockopt could be called like this:
 *   sock.setsockopt(:SOCKET, :REUSEADDR, true)
 *   sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
 *   sock.setsockopt(Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true))
 *
 * Some socket options are integers with numeric values, in this case
 * #setsockopt could be called like this:
 *   sock.setsockopt(:IP, :TTL, 255)
 *   sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255)
 *   sock.setsockopt(Socket::Option.int(:INET, :IP, :TTL, 255))
 *
 * Option values may be structs. Passing them can be complex as it involves
 * examining your system headers to determine the correct definition. An
 * example is an +ip_mreq+, which may be defined in your system headers as:
 *   struct ip_mreq {
 *     struct  in_addr imr_multiaddr;
 *     struct  in_addr imr_interface;
 *   };
 *
 * In this case #setsockopt could be called like this:
 *   optval = IPAddr.new("224.0.0.251").hton +
 *            IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton
 *   sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval)
 *
*/
static VALUE
bsock_setsockopt(int argc, VALUE *argv, VALUE sock)
{
UNRUBBY_SOCKET_HACK;
    VALUE lev, optname, val;
    int family, level, option;
    rb_io_t *fptr;
    int i;
    char *v;
    int vlen;

    if (argc == 1) {
        lev = rb_funcall(argv[0], rb_intern("level"), 0);
        optname = rb_funcall(argv[0], rb_intern("optname"), 0);
        val = rb_funcall(argv[0], rb_intern("data"), 0);
    }
    else {
        rb_scan_args(argc, argv, "30", &lev, &optname, &val);
    }

    rb_secure(2);
    GetOpenFile(sock, fptr);
    family = rsock_getfamily(fptr->fd);
    level = rsock_level_arg(family, lev);
    option = rsock_optname_arg(family, level, optname);

    switch (TYPE(val)) {
      case T_FIXNUM:
	i = FIX2INT(val);
	goto numval;
      case T_FALSE:
	i = 0;
	goto numval;
      case T_TRUE:
	i = 1;
      numval:
	v = (char*)&i; vlen = (int)sizeof(i);
	break;
      default:
	StringValue(val);
	v = RSTRING_PTR(val);
	vlen = RSTRING_LENINT(val);
	break;
    }

#define rb_sys_fail_path(path) rb_sys_fail(NIL_P(path) ? 0 : RSTRING_PTR(path))

    rb_io_check_closed(fptr);
    if (setsockopt(fptr->fd, level, option, v, vlen) < 0)
	rb_sys_fail_path(fptr->pathv);

    return INT2FIX(0);
}
Ejemplo n.º 16
0
/*
 *  call-seq:
 *     HMAC.new(key, digest) -> hmac
 *
 * Returns an instance of OpenSSL::HMAC set with the key and digest
 * algorithm to be used. The instance represents the initial state of
 * the message authentication code before any data has been processed.
 * To process data with it, use the instance method #update with your
 * data as an argument.
 *
 * === Example
 *
 *	key = 'key'
 * 	digest = OpenSSL::Digest.new('sha1')
 * 	instance = OpenSSL::HMAC.new(key, digest)
 * 	#=> f42bb0eeb018ebbd4597ae7213711ec60760843f
 * 	instance.class
 * 	#=> OpenSSL::HMAC
 *
 * === A note about comparisons
 *
 * Two instances won't be equal when they're compared, even if they have the
 * same value. Use #to_s or #hexdigest to return the authentication code that
 * the instance represents. For example:
 *
 *	other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
 *  	#=> f42bb0eeb018ebbd4597ae7213711ec60760843f
 *  	instance
 *  	#=> f42bb0eeb018ebbd4597ae7213711ec60760843f
 *  	instance == other_instance
 *  	#=> false
 *  	instance.to_s == other_instance.to_s
 *  	#=> true
 *
 */
static VALUE
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
{
    HMAC_CTX *ctx;

    StringValue(key);
    GetHMAC(self, ctx);
    HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
		 ossl_evp_get_digestbyname(digest), NULL);

    return self;
}
Ejemplo n.º 17
0
static ASN1_STRING*
obj_to_asn1str(VALUE obj)
{
    ASN1_STRING *str;

    StringValue(obj);
    if(!(str = ASN1_STRING_new()))
	ossl_raise(eASN1Error, NULL);
    ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj));

    return str;
}
Ejemplo n.º 18
0
/*
 *  call-seq:
 *     HMAC.new(key, digest) -> hmac
 *
 * Returns an instance of OpenSSL::HMAC set with the key and digest
 * algorithm to be used. The instance represents the initial state of
 * the message authentication code before any data has been processed.
 * To process data with it, use the instance method #update with your
 * data as an argument.
 *
 * === Example
 *
 *	key = 'key'
 * 	digest = OpenSSL::Digest.new('sha1')
 * 	instance = OpenSSL::HMAC.new(key, digest)
 * 	#=> f42bb0eeb018ebbd4597ae7213711ec60760843f
 * 	instance.class
 * 	#=> OpenSSL::HMAC
 *
 * === A note about comparisons
 *
 * Two instances won't be equal when they're compared, even if they have the
 * same value. Use #to_s or #hexdigest to return the authentication code that
 * the instance represents. For example:
 *
 *	other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
 *  	#=> f42bb0eeb018ebbd4597ae7213711ec60760843f
 *  	instance
 *  	#=> f42bb0eeb018ebbd4597ae7213711ec60760843f
 *  	instance == other_instance
 *  	#=> false
 *  	instance.to_s == other_instance.to_s
 *  	#=> true
 *
 */
static VALUE
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
{
    HMAC_CTX *ctx;

    StringValue(key);
    GetHMAC(self, ctx);
    HMAC_Init(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
		 GetDigestPtr(digest));

    return self;
}
Ejemplo n.º 19
0
static ASN1_STRING*
obj_to_asn1derstr(VALUE obj)
{
    ASN1_STRING *a1str;
    VALUE str;

    str = ossl_to_der(obj);
    if(!(a1str = ASN1_STRING_new()))
	ossl_raise(eASN1Error, NULL);
    ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str));

    return a1str;
}
Ejemplo n.º 20
0
/*
 * call-seq:
 *    spki.challenge = str => string
 *
 * === Parameters
 * * +str+ - the challenge string to be set for this instance
 *
 * Sets the challenge to be associated with the SPKI. May be used by the
 * server, e.g. to prevent replay.
 */
static VALUE
ossl_spki_set_challenge(VALUE self, VALUE str)
{
    NETSCAPE_SPKI *spki;

    StringValue(str);
    GetSPKI(self, spki);
    if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str),
			 RSTRING_LENINT(str))) {
	ossl_raise(eSPKIError, NULL);
    }

    return str;
}
Ejemplo n.º 21
0
static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format)
{
    EC_KEY *ec;
    BIO *out;
    int i = -1;
    int private = 0;
    char *password = NULL;
    VALUE str;

    Require_EC_KEY(self, ec);

    if (EC_KEY_get0_public_key(ec) == NULL)
        ossl_raise(eECError, "can't export - no public key set");

    if (EC_KEY_check_key(ec) != 1)
	ossl_raise(eECError, "can't export - EC_KEY_check_key failed");

    if (EC_KEY_get0_private_key(ec))
        private = 1;

    if (!(out = BIO_new(BIO_s_mem())))
        ossl_raise(eECError, "BIO_new(BIO_s_mem())");

    switch(format) {
    case EXPORT_PEM:
    	if (private) {
	    const EVP_CIPHER *cipher;
	    if (!NIL_P(ciph)) {
		cipher = GetCipherPtr(ciph);
		if (!NIL_P(pass)) {
		    StringValue(pass);
		    if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
			ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
		    password = RSTRING_PTR(pass);
		}
	    }
	    else {
		cipher = NULL;
	    }
            i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
    	} else {
            i = PEM_write_bio_EC_PUBKEY(out, ec);
        }

    	break;
    case EXPORT_DER:
        if (private) {
            i = i2d_ECPrivateKey_bio(out, ec);
        } else {
Ejemplo n.º 22
0
static ASN1_BIT_STRING*
obj_to_asn1bstr(VALUE obj, long unused_bits)
{
    ASN1_BIT_STRING *bstr;

    if(unused_bits < 0) unused_bits = 0;
    StringValue(obj);
    if(!(bstr = ASN1_BIT_STRING_new()))
	ossl_raise(eASN1Error, NULL);
    ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj));
    bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
    bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07);

    return bstr;
}
Ejemplo n.º 23
0
BIO *
ossl_obj2bio(volatile VALUE *pobj)
{
    VALUE obj = *pobj;
    BIO *bio;

    if (RB_TYPE_P(obj, T_FILE))
	obj = rb_funcallv(obj, rb_intern("read"), 0, NULL);
    StringValue(obj);
    bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj));
    if (!bio)
	ossl_raise(eOSSLError, "BIO_new_mem_buf");
    *pobj = obj;
    return bio;
}
Ejemplo n.º 24
0
static VALUE
mWBXML2_convert(VALUE self, VALUE input, void *conv, mWBXML2_run_conv run_conv) {
  WBXMLError code = WBXML_OK;
  WB_UTINY *output_buf_ptr = NULL;
  WB_ULONG output_len = 0;
  VALUE retval = Qnil;
  if (WBXML_OK != (code = run_conv(conv, (WB_UTINY*)StringValuePtr(input), 
				   RSTRING_LENINT(input),
				   &output_buf_ptr,
				   &output_len))) {
    rb_raise(rb_eRuntimeError, "conversion error: %s.", wbxml_errors_string(code));
  }
  retval = rb_str_new((char*)output_buf_ptr, output_len);
  free(output_buf_ptr);
  return retval;
}
Ejemplo n.º 25
0
static VALUE method_deserialize(VALUE self, VALUE bson, VALUE opts) {
    const char* buffer = RSTRING_PTR(bson);
    int remaining = RSTRING_LENINT(bson);
    struct deserialize_opts deserialize_opts;

    deserialize_opts.compile_regex = 1;
    if (rb_funcall(opts, rb_intern("has_key?"), 1, ID2SYM(rb_intern("compile_regex"))) == Qtrue &&
        rb_hash_aref(opts, ID2SYM(rb_intern("compile_regex"))) == Qfalse) {
        deserialize_opts.compile_regex = 0;
    }

    // NOTE we just swallow the size and end byte here
    buffer += 4;
    remaining -= 5;

    return elements_to_hash(buffer, remaining, &deserialize_opts);
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
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;
    int in_len;
    int out_len;

    StringValue(data);

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

    GetCipher(self, ctx);

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

    return data;
}
Ejemplo n.º 28
0
Archivo: init.c Proyecto: Chatto/VGdesk
/*
 * call-seq:
 *   sdbm.key(value) -> key
 *
 * Returns the +key+ associated with the given +value+. If more than one
 * +key+ corresponds to the given +value+, then the first key to be found
 * will be returned. If no keys are found, +nil+ will be returned.
 */
static VALUE
fsdbm_key(VALUE obj, VALUE valstr)
{
    datum key, val;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(valstr);
    val.dptr = RSTRING_PTR(valstr);
    val.dsize = RSTRING_LENINT(valstr);

    GetDBM2(obj, dbmp, dbm);
    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
	val = sdbm_fetch(dbm, key);
	if (val.dsize == RSTRING_LEN(valstr) &&
	    memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
	    return rb_external_str_new(key.dptr, key.dsize);
    }
    return Qnil;
}
Ejemplo n.º 29
0
Archivo: init.c Proyecto: Chatto/VGdesk
static VALUE
fsdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
{
    datum key, value;
    struct dbmdata *dbmp;
    DBM *dbm;

    ExportStringValue(keystr);
    key.dptr = RSTRING_PTR(keystr);
    key.dsize = RSTRING_LENINT(keystr);

    GetDBM2(obj, dbmp, dbm);
    value = sdbm_fetch(dbm, key);
    if (value.dptr == 0) {
	if (ifnone == Qnil && rb_block_given_p())
	    return rb_yield(rb_external_str_new(key.dptr, key.dsize));
	return ifnone;
    }
    return rb_external_str_new(value.dptr, value.dsize);
}
Ejemplo n.º 30
0
static VALUE
ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
{
    OCSP_BASICRESP *bs;
    VALUE val;
    int ret;

    rb_scan_args(argc, argv, "01", &val);
    if(NIL_P(val)) {
	GetOCSPBasicRes(self, bs);
	ret = OCSP_basic_add1_nonce(bs, NULL, -1);
    }
    else{
	StringValue(val);
	GetOCSPBasicRes(self, bs);
	ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
    }
    if(!ret) ossl_raise(eOCSPError, NULL);

    return self;
}