# class OpenSSL::X509::Store

The `X509` certificate store holds trusted CA certificates used to verify peer certificates.

The easiest way to create a useful certificate store is:

    cert_store = OpenSSL::X509::Store.new
    cert_store.set_default_paths

This will use your system's built-in certificates.

If your system does not have a default set of certificates you can obtain a set extracted from Mozilla CA certificate store by cURL maintainers here: curl.haxx.se/docs/caextract.html (You may wish to use the firefox-db2pem.sh script to extract the certificates from a local install to avoid man-in-the-middle attacks.)

After downloading or generating a cacert.pem from the above link you can create a certificate store from the pem file like this:

    cert_store = OpenSSL::X509::Store.new
    cert_store.add_file 'cacert.pem'

The certificate store can be used with an SSLSocket like this:

    ssl_context = OpenSSL::SSL::SSLContext.new
    ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
    ssl_context.cert_store = cert_store

    tcp_socket = TCPSocket.open 'example.com', 443

    ssl_socket = OpenSSL::SSL::SSLSocket.new tcp_socket, ssl_context

### Attributes

chain[R]

The certificate chain constructed by the last call of `verify`.

error[R]

The error code set by the last call of `verify`.

error_string[R]

The description for the error code set by the last call of `verify`.

verify_callback[R]

The callback for additional certificate verification. It is invoked for each untrusted certificate in the chain.

The callback is invoked with two values, a boolean that indicates if the pre-verification by `OpenSSL` has succeeded or not, and the `StoreContext` in use. The callback must return either true or false.

### Public Class Methods

X509::Store.new → store click to toggle source

Creates a new `X509::Store`.

    static VALUE
    ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
    {
        X509_STORE *store;

    /* BUG: This method takes any number of arguments but appears to ignore them. */
        GetX509Store(self, store);
    #if !defined(HAVE_OPAQUE_OPENSSL)
        /* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */
        store->ex_data.sk = NULL;
    #endif
        X509_STORE_set_verify_cb(store, x509store_verify_cb);
        ossl_x509store_set_vfy_cb(self, Qnil);

        /* last verification status */
        rb_iv_set(self, "@error", Qnil);
        rb_iv_set(self, "@error_string", Qnil);
        rb_iv_set(self, "@chain", Qnil);
        rb_iv_set(self, "@time", Qnil);

        return self;
    }

### Public Instance Methods

add_cert(cert) click to toggle source

Adds the `OpenSSL::X509::Certificate` `cert` to the certificate store.

    static VALUE
    ossl_x509store_add_cert(VALUE self, VALUE arg)
    {
        X509_STORE *store;
        X509 *cert;

        cert = GetX509CertPtr(arg); /* NO NEED TO DUP */
        GetX509Store(self, store);
        if (X509_STORE_add_cert(store, cert) != 1){
            ossl_raise(eX509StoreError, NULL);
        }

        return self;
    }

add_crl(crl) → self click to toggle source

Adds the `OpenSSL::X509::CRL` `crl` to the store.

    static VALUE
    ossl_x509store_add_crl(VALUE self, VALUE arg)
    {
        X509_STORE *store;
        X509_CRL *crl;

        crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */
        GetX509Store(self, store);
        if (X509_STORE_add_crl(store, crl) != 1){
            ossl_raise(eX509StoreError, NULL);
        }

        return self;
    }

add_file(file) → self click to toggle source

Adds the certificates in `file` to the certificate store. The `file` can contain multiple PEM-encoded certificates.

    static VALUE
    ossl_x509store_add_file(VALUE self, VALUE file)
    {
        X509_STORE *store;
        X509_LOOKUP *lookup;
        char *path = NULL;

        if(file != Qnil){
            rb_check_safe_obj(file);
            path = StringValueCStr(file);
        }
        GetX509Store(self, store);
        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
        if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
        if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){
            ossl_raise(eX509StoreError, NULL);
        }
    #if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
        /*
         * X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file()
         * did not check the return value of X509_STORE_add_{cert,crl}(), leaking
         * "cert already in hash table" errors on the error queue, if duplicate
         * certificates are found. This will be fixed by OpenSSL 1.1.1.
         */
        ossl_clear_error();
    #endif

        return self;
    }

add_path(path) → self click to toggle source

Adds `path` as the hash dir to be looked up by the store.

    static VALUE
    ossl_x509store_add_path(VALUE self, VALUE dir)
    {
        X509_STORE *store;
        X509_LOOKUP *lookup;
        char *path = NULL;

        if(dir != Qnil){
            rb_check_safe_obj(dir);
            path = StringValueCStr(dir);
        }
        GetX509Store(self, store);
        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
        if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
        if(X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1){
            ossl_raise(eX509StoreError, NULL);
        }

        return self;
    }

flags = flag click to toggle source

Sets `flag` to the `Store`. `flag` consists of zero or more of the constants defined in with name V_FLAG_* or'ed together.

    static VALUE
    ossl_x509store_set_flags(VALUE self, VALUE flags)
    {
        X509_STORE *store;
        long f = NUM2LONG(flags);

        GetX509Store(self, store);
        X509_STORE_set_flags(store, f);

        return flags;
    }

purpose = purpose click to toggle source

Sets the store's purpose to `purpose`. If specified, the verifications on the store will check every untrusted certificate's extensions are consistent with the purpose. The purpose is specified by constants:

- X509::PURPOSE_SSL_CLIENT

- X509::PURPOSE_SSL_SERVER

- X509::PURPOSE_NS_SSL_SERVER

- X509::PURPOSE_SMIME_SIGN

- X509::PURPOSE_SMIME_ENCRYPT

- X509::PURPOSE_CRL_SIGN

- X509::PURPOSE_ANY

- X509::PURPOSE_OCSP_HELPER

- X509::PURPOSE_TIMESTAMP_SIGN

    static VALUE
    ossl_x509store_set_purpose(VALUE self, VALUE purpose)
    {
        X509_STORE *store;
        int p = NUM2INT(purpose);

        GetX509Store(self, store);
        X509_STORE_set_purpose(store, p);

        return purpose;
    }

set_default_paths click to toggle source

Configures `store` to look up CA certificates from the system default certificate store as needed basis. The location of the store can usually be determined by:

- OpenSSL::X509::DEFAULT_CERT_FILE

- OpenSSL::X509::DEFAULT_CERT_DIR

    static VALUE
    ossl_x509store_set_default_paths(VALUE self)
    {
        X509_STORE *store;

        GetX509Store(self, store);
        if (X509_STORE_set_default_paths(store) != 1){
            ossl_raise(eX509StoreError, NULL);
        }

        return Qnil;
    }

time = time click to toggle source

Sets the time to be used in verifications.

    static VALUE
    ossl_x509store_set_time(VALUE self, VALUE time)
    {
        rb_iv_set(self, "@time", time);
        return time;
    }

trust = trust click to toggle source

    static VALUE
    ossl_x509store_set_trust(VALUE self, VALUE trust)
    {
        X509_STORE *store;
        int t = NUM2INT(trust);

        GetX509Store(self, store);
        X509_STORE_set_trust(store, t);

        return trust;
    }

verify(cert, chain = nil) → true | false click to toggle source

Performs a certificate verification on the `OpenSSL::X509::Certificate` `cert`.

`chain` can be an array of `OpenSSL::X509::Certificate` that is used to construct the certificate chain.

If a block is given, it overrides the callback set by `verify_callback=`.

After finishing the verification, the error information can be retrieved by `error`, `error_string`, and the resuting complete certificate chain can be retrieved by `chain`.

    static VALUE
    ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
    {
        VALUE cert, chain;
        VALUE ctx, proc, result;

        rb_scan_args(argc, argv, "11", &cert, &chain);
        ctx = rb_funcall(cX509StoreContext, rb_intern("new"), 3, self, cert, chain);
        proc = rb_block_given_p() ?  rb_block_proc() :
               rb_iv_get(self, "@verify_callback");
        rb_iv_set(ctx, "@verify_callback", proc);
        result = rb_funcall(ctx, rb_intern("verify"), 0);

        rb_iv_set(self, "@error", ossl_x509stctx_get_err(ctx));
        rb_iv_set(self, "@error_string", ossl_x509stctx_get_err_string(ctx));
        rb_iv_set(self, "@chain", ossl_x509stctx_get_chain(ctx));

        return result;
    }

verify_callback=(p1) click to toggle source

General callback for `OpenSSL` verify

    static VALUE
    ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
    {
        X509_STORE *store;

        GetX509Store(self, store);
        X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb);
        rb_iv_set(self, "@verify_callback", cb);

        return cb;
    }