コード例 #1
0
static VALUE
ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
{
    VALUE pass, name, pkey, cert, ca;
    VALUE obj;
    char *passphrase, *friendlyname;
    EVP_PKEY *key;
    X509 *x509;
    STACK_OF(X509) *x509s;
    PKCS12 *p12;
    
    rb_scan_args(argc, argv, "41", &pass, &name, &pkey, &cert, &ca);
    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);
    p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s,
                        0, 0, 0, 0, 0);
    sk_X509_pop_free(x509s, X509_free);
    if(!p12) ossl_raise(ePKCS12Error, NULL);
    WrapPKCS12(cPKCS12, obj, p12);

    return obj;
}
コード例 #2
0
ファイル: ossl_ns_spki.c プロジェクト: Capcah/openssl
/*
 * call-seq:
 *    spki.public_key = pub => pkey
 *
 * === Parameters
 * * +pub+ - the public key to be set for this instance
 *
 * Sets the public key to be associated with the SPKI, an instance of
 * OpenSSL::PKey. This should be the public key corresponding to the
 * private key used for signing the SPKI.
 */
static VALUE
ossl_spki_set_public_key(VALUE self, VALUE key)
{
    NETSCAPE_SPKI *spki;

    GetSPKI(self, spki);
    if (!NETSCAPE_SPKI_set_pubkey(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
	ossl_raise(eSPKIError, NULL);
    }

    return key;
}
コード例 #3
0
ファイル: ossl_ssl.c プロジェクト: 2220142/ruby
static DH*
ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
{
    VALUE args[3];
    int status, success;

    args[0] = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
    args[1] = INT2FIX(is_export);
    args[2] = INT2FIX(keylength);
    success = rb_protect((VALUE(*)_((VALUE)))ossl_call_tmp_dh_callback,
                         (VALUE)args, &status);
    if (status || !success) return NULL;

    return GetPKeyPtr(ossl_ssl_get_tmp_dh(args[0]))->pkey.dh;
}
コード例 #4
0
static VALUE 
ossl_x509crl_verify(VALUE self, VALUE key)
{
    X509_CRL *crl;
    int ret;

    GetX509CRL(self, crl);
    if ((ret = X509_CRL_verify(crl, GetPKeyPtr(key))) < 0) {
	ossl_raise(eX509CRLError, NULL);
    }
    if (ret == 1) {
	return Qtrue;
    }

    return Qfalse;
}
コード例 #5
0
ファイル: ossl_x509crl.c プロジェクト: gferguson-gd/ruby
static VALUE
ossl_x509crl_verify(VALUE self, VALUE key)
{
    X509_CRL *crl;

    GetX509CRL(self, crl);
    switch (X509_CRL_verify(crl, GetPKeyPtr(key))) {
      case 1:
	return Qtrue;
      case 0:
	ossl_clear_error();
	return Qfalse;
      default:
	ossl_raise(eX509CRLError, NULL);
    }
}
コード例 #6
0
ファイル: ossl_ns_spki.c プロジェクト: Capcah/openssl
/*
 * call-seq:
 *    spki.verify(key) => boolean
 *
 * === Parameters
 * * +key+ - the public key to be used for verifying the SPKI signature
 *
 * Returns +true+ if the signature is valid, +false+ otherwise. To verify an
 * SPKI, the public key contained within the SPKI should be used.
 */
static VALUE
ossl_spki_verify(VALUE self, VALUE key)
{
    NETSCAPE_SPKI *spki;

    GetSPKI(self, spki);
    switch (NETSCAPE_SPKI_verify(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
    case 0:
	return Qfalse;
    case 1:
	return Qtrue;
    default:
	ossl_raise(eSPKIError, NULL);
    }
    return Qnil; /* dummy */
}
コード例 #7
0
ファイル: ossl_pkcs12.c プロジェクト: fi8on/ruby
/*
 * 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;
}
コード例 #8
0
ファイル: ossl_ssl.c プロジェクト: 2220142/ruby
static VALUE
ossl_call_tmp_dh_callback(VALUE *args)
{
    SSL *ssl;
    VALUE cb, dh;
    EVP_PKEY *pkey;

    Data_Get_Struct(args[0], SSL, ssl);
    cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx);
    if (NIL_P(cb)) return Qfalse;
    dh = rb_funcall(cb, rb_intern("call"), 3, args[0], args[1], args[2]);
    pkey = GetPKeyPtr(dh);
    if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) return Qfalse;
    ossl_ssl_set_tmp_dh(args[0], dh);

    return Qtrue;
}
コード例 #9
0
ファイル: ossl_ssl.c プロジェクト: 2220142/ruby
static VALUE
ossl_call_client_cert_cb(VALUE obj)
{
    VALUE cb, ary, cert, key;
    SSL *ssl;

    Data_Get_Struct(obj, SSL, ssl);
    cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx);
    if (NIL_P(cb)) return Qfalse;
    ary = rb_funcall(cb, rb_intern("call"), 1, obj);
    Check_Type(ary, T_ARRAY);
    GetX509CertPtr(cert = rb_ary_entry(ary, 0));
    GetPKeyPtr(key = rb_ary_entry(ary, 1));
    ossl_ssl_set_x509(obj, cert);
    ossl_ssl_set_key(obj, key);

    return Qtrue;
}
コード例 #10
0
ファイル: ossl_ssl.c プロジェクト: 2220142/ruby
/*
 * call-seq:
 *    ctx.setup => Qtrue # first time
 *    ctx.setup => nil # thereafter
 *
 * This method is called automatically when a new SSLSocket is created.
 * Normally you do not need to call this method (unless you are writing an extension in C).
 */
static VALUE
ossl_sslctx_setup(VALUE self)
{
    SSL_CTX *ctx;
    X509 *cert = NULL, *client_ca = NULL;
    X509_STORE *store;
    EVP_PKEY *key = NULL;
    char *ca_path = NULL, *ca_file = NULL;
    int i, verify_mode;
    VALUE val;

    if(OBJ_FROZEN(self)) return Qnil;
    Data_Get_Struct(self, SSL_CTX, ctx);

#if !defined(OPENSSL_NO_DH)
    if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){
	SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
    }
    else{
	SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback);
    }
#endif
    SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self);

    val = ossl_sslctx_get_cert_store(self);
    if(!NIL_P(val)){
	/*
         * WORKAROUND:
	 *   X509_STORE can count references, but
	 *   X509_STORE_free() doesn't care it.
	 *   So we won't increment it but mark it by ex_data.
	 */
        store = GetX509StorePtr(val); /* NO NEED TO DUP */
        SSL_CTX_set_cert_store(ctx, store);
        SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);
    }

    val = ossl_sslctx_get_extra_cert(self);
    if(!NIL_P(val)){
	rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
    }

    /* private key may be bundled in certificate file. */
    val = ossl_sslctx_get_cert(self);
    cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
    val = ossl_sslctx_get_key(self);
    key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */
    if (cert && key) {
        if (!SSL_CTX_use_certificate(ctx, cert)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_certificate:");
        }
        if (!SSL_CTX_use_PrivateKey(ctx, key)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey:");
        }
        if (!SSL_CTX_check_private_key(ctx)) {
            ossl_raise(eSSLError, "SSL_CTX_check_private_key:");
        }
    }

    val = ossl_sslctx_get_client_ca(self);
    if(!NIL_P(val)){
	if(TYPE(val) == T_ARRAY){
	    for(i = 0; i < RARRAY_LEN(val); i++){
		client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]);
        	if (!SSL_CTX_add_client_CA(ctx, client_ca)){
		    /* Copies X509_NAME => FREE it. */
        	    ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
        	}
	    }
        }
	else{
	    client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
            if (!SSL_CTX_add_client_CA(ctx, client_ca)){
		/* Copies X509_NAME => FREE it. */
        	ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
            }
	}
    }

    val = ossl_sslctx_get_ca_file(self);
    ca_file = NIL_P(val) ? NULL : StringValuePtr(val);
    val = ossl_sslctx_get_ca_path(self);
    ca_path = NIL_P(val) ? NULL : StringValuePtr(val);
    if(ca_file || ca_path){
	if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
	    rb_warning("can't set verify locations");
    }

    val = ossl_sslctx_get_verify_mode(self);
    verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
    SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
    if (RTEST(ossl_sslctx_get_client_cert_cb(self)))
	SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);

    val = ossl_sslctx_get_timeout(self);
    if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));

    val = ossl_sslctx_get_verify_dep(self);
    if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val));

    val = ossl_sslctx_get_options(self);
    if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val));
    rb_obj_freeze(self);

    val = ossl_sslctx_get_sess_id_ctx(self);
    if (!NIL_P(val)){
	StringValue(val);
	if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
					    RSTRING_LEN(val))){
	    ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:");
	}
    }

    if (RTEST(rb_iv_get(self, "@session_get_cb"))) {
	SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
	OSSL_Debug("SSL SESSION get callback added");
    }
    if (RTEST(rb_iv_get(self, "@session_new_cb"))) {
	SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
	OSSL_Debug("SSL SESSION new callback added");
    }
    if (RTEST(rb_iv_get(self, "@session_remove_cb"))) {
	SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
	OSSL_Debug("SSL SESSION remove callback added");
    }

#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
    val = rb_iv_get(self, "@servername_cb");
    if (!NIL_P(val)) {
        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
	OSSL_Debug("SSL TLSEXT servername callback added");
    }
#endif

    return Qtrue;
}