класс OpenSSL::X509::Store
Хранилище X509 сертификатов содержит доверенные сертификаты CA, используемые для проверки сертификатов партнёров.
Самый простой способ создать полезное хранилище сертификатов:
cert_store = OpenSSL::X509::Store.new cert_store.set_default_paths
Это будет использовать встроенные сертификаты вашей системы.
Если ваша система не имеет набора сертификатов по умолчанию, вы можете получить набор, извлечённый из хранилища сертификатов Mozilla CA, от разработчиков cURL здесь: curl.haxx.se/docs/caextract.html (Возможно, вам понадобится использовать скрипт firefox-db2pem.sh для извлечения сертификатов из локальной установки, чтобы избежать атак «человек посередине».)
После загрузки или генерации cacert.pem по ссылке выше, вы можете создать хранилище сертификатов из файла pem так:
cert_store = OpenSSL::X509::Store.new cert_store.add_file 'cacert.pem'
Хранилище сертификатов можно использовать с SSLSocket так:
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
Атрибуты
Цепочка сертификатов, построенная последним вызовом verify.
Код ошибки, установленный последним вызовом verify.
Описание кода ошибки, установленного последним вызовом verify.
Обработчик для дополнительной проверки сертификатов. Вызывается для каждого недоверенного сертификата в цепочке.
Обработчик вызывается с двумя значениями: логическим значением, указывающим, удалось ли предварительная проверка от OpenSSL, и контекстом StoreContext, используемым в данный момент. Обработчик должен вернуть true или false.
Открытые методы класса
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;
} Создаёт новое хранилище X509::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;
} Добавляет OpenSSL::X509::Certificate cert в хранилище сертификатов.
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;
} Добавляет OpenSSL::X509::CRL crl в хранилище.
static VALUE
ossl_x509store_add_file(VALUE self, VALUE file)
{
X509_STORE *store;
X509_LOOKUP *lookup;
char *path = NULL;
if(file != Qnil){
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;
} Добавляет сертификаты из файла file в хранилище. file — путь к файлу, содержащему один или несколько сертификатов в формате PEM, соединённых вместе.
static VALUE
ossl_x509store_add_path(VALUE self, VALUE dir)
{
X509_STORE *store;
X509_LOOKUP *lookup;
char *path = NULL;
if(dir != Qnil){
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;
} Добавляет path в качестве каталога хешей для поиска в хранилище.
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;
} Устанавливает flags для Store. flags состоит из нуля или более констант, определённых в имени V_FLAG_* и объединённых с операцией OR.
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;
} Устанавливает назначение хранилища в purpose. Если указано, проверки в хранилище будут проверять, что все расширения каждого недоверенного сертификата согласуются с назначением. Назначение задаётся константами:
-
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_default_paths(VALUE self)
{
X509_STORE *store;
GetX509Store(self, store);
if (X509_STORE_set_default_paths(store) != 1){
ossl_raise(eX509StoreError, NULL);
}
return Qnil;
} Настраивает store на поиск сертификатов CA в системном хранилище сертификатов по мере необходимости. Расположение хранилища обычно можно определить по:
-
OpenSSL::X509::DEFAULT_CERT_FILE
-
OpenSSL::X509::DEFAULT_CERT_DIR
static VALUE
ossl_x509store_set_time(VALUE self, VALUE time)
{
rb_iv_set(self, "@time", time);
return time;
} Устанавливает время, используемое в проверках.
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;
} 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;
} Выполняет проверку сертификата OpenSSL::X509::Certificate cert.
chain может быть массивом OpenSSL::X509::Certificate, используемым для построения цепочки сертификатов.
Если задан блок, он переопределяет обработчик, установленный verify_callback=.
После завершения проверки информацию об ошибках можно получить с помощью error, error_string, а полную цепочку сертификатов — с помощью chain.
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;
} Общий обработчик для OpenSSL проверки
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.