1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/shike-boringssl

Клонировать/Скачать
API-CONVENTIONS.md 13 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 01.12.2024 14:16 972c04e

Ссылка выпущена. Для совместимости с OpenSSL эти функции возвращают int, но вызывающие стороны могут предполагать, что они всегда успешно возвращают единицу, потому что счётчики ссылок используют арифметику насыщения.

Потребителям C++ рекомендуется использовать bssl::UniquePtr для управления объектами, выделенными в куче. bssl::UniquePtr<T>, как и другие типы, предварительно объявлен в openssl/base.h. Код, которому нужен доступ к свободным функциям, например код, который уничтожает bssl::UniquePtr, должен включать заголовок соответствующего модуля. (Это соответствует связи std::unique_ptr с предварительными объявлениями.) Обратите внимание: несмотря на название, bssl::UniquePtr также используется с типами, подсчитывающими ссылки. Он владеет единственной ссылкой на объект. Чтобы взять дополнительную ссылку, используйте функцию bssl::UpRef, которая вернёт отдельный bssl::UniquePtr.

Другие типы в BoringSSL размещаются в стеке, такие как EVP_MD_CTX. Эти типы могут быть размещены в стеке или встроены в другой объект. Однако их всё равно необходимо инициализировать перед использованием.

Каждый размещённый в стеке объект в BoringSSL имеет нулевое состояние, аналогичное инициализации указателя значением NULL. В этом состоянии объект может быть не полностью инициализирован, но безопасно вызывать функции очистки. Вход в нулевое состояние не может завершиться ошибкой. (Обычно это memset(0).)

Функция для входа в нулевое состояние называется EVP_MD_CTX_init или CBB_zero и всегда возвращает void. Чтобы освободить ресурсы, связанные с типом, вызовите функцию очистки, которая называется EVP_MD_CTX_cleanup. Функцию очистки необходимо вызывать на всех путях кода, независимо от успеха или неудачи. Например:

uint8_t md[EVP_MAX_MD_SIZE];
unsigned md_len;
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);  /* Enter the zero state. */
int ok = EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL) &&
         EVP_DigestUpdate(&ctx, "hello ", 6) &&
         EVP_DigestUpdate(&ctx, "world", 5) &&
         EVP_DigestFinal_ex(&ctx, md, &md_len);
EVP_MD_CTX_cleanup(&ctx);  /* Release |ctx|. */

Обратите внимание, что EVP_MD_CTX_cleanup вызывается независимо от того, успешно ли выполнены операции EVP_Digest*. Более сложные функции C могут использовать шаблон goto err:

  int ret = 0;
  EVP_MD_CTX ctx;
  EVP_MD_CTX_init(&ctx);

  if (!some_other_operation()) {
    goto err;
  }

  uint8_t md[EVP_MAX_MD_SIZE];
  unsigned md_len;
  if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL) ||
      !EVP_DigestUpdate(&ctx, "hello ", 6) ||
      !EVP_DigestUpdate(&ctx, "world", 5) ||
      !EVP_DigestFinal_ex(&ctx, md, &md_len) {
    goto err;
  }

  ret = 1;

err:
  EVP_MD_CTX_cleanup(&ctx);
  return ret;

Обратите внимание: поскольку ctx установлен в нулевое состояние перед любыми сбоями, EVP_MD_CTX_cleanup безопасно вызывать, даже если первая операция завершится неудачно до EVP_DigestInit_ex. Однако было бы незаконно переместить вызов EVP_MD_CTX_init после вызова some_other_operation.

Как правило, вводите нулевое состояние размещённых в стеке структур в том же месте, где они объявлены.

Потребителям C++ рекомендуется использовать оболочки с именами вроде bssl::ScopedEVP_MD_CTX, определённые в заголовке соответствующего модуля. Эти оболочки автоматически инициализируются нулевым состоянием и автоматически очищаются.

Несколько типов, таких как SHA_CTX, являются типами только для данных и не требуют очистки. Обычно они используются для низкоуровневых криптографических операций. Эти типы можно свободно использовать без специальных соглашений об очистке.

Когда вы работаете с выделенными объектами, важно думать о владении каждым объектом или о том, какой код отвечает за его освобождение. Это соответствует соответствующему понятию в языках более высокого уровня, таких как C++ и Rust.

Владение применяется как к типам с уникальным владением, так и к типам со счётчиками ссылок. Для последних владение означает, что код отвечает за освобождение одной ссылки. Обратите внимание: ссылка в BoringSSL относится к увеличению (и возможному уменьшению) счётчика ссылок объекта, а не к T& в C++. «Take a reference» означает увеличить счётчик ссылок и взять на себя ответственность за его уменьшение.

Поскольку API BoringSSL в основном написаны на C, обязательства по владению и времени жизни не строго аннотированы в сигнатурах типов или проверяются во время компиляции. Вместо этого они описаны в документации по API. В этом разделе описываются некоторые соглашения.

Если иное не задокументировано, функции не берут на себя владение аргументами-указателями. Обычно указатель должен оставаться действительным в течение всего вызова функции. Функция может внутренне скопировать информацию из аргумента или взять ссылку, но вызывающий объект может освободить свою копию или ссылку в любой момент после завершения вызова.

Вместо этого функция может быть задокументирована как принимающая или передающая владение указателем. Вызывающий объект должен владеть объектом перед вызовом функции, и после передачи он больше им не владеет. Как следствие, вызывающий объект также может больше не ссылаться на объект без отдельной гарантии времени жизни. Функция даже может освободить объект до возврата. Поэтому вызывающие объекты, которые хотят независимо сохранить переданный объект, должны взять ссылку или сделать копию перед передачей. Также вызывающим объектам следует обратить внимание на то, что функция задокументирована для передачи указателей безусловно или только при успешном выполнении. В отличие от C++ и Rust, функции в BoringSSL обычно передают только при успешном выполнении.

Аналогично выходные указатели могут быть владеющими или невладеющими. Если иное не задокументировано, функции выводят невладеющие указатели. Вызывающий объект не отвечает за освобождение выходного указателя, но он не должен использовать указатель после окончания его времени жизни. Указатель может быть освобождён при освобождении родительского объекта или даже раньше при изменении состояния родительского объекта.

Если задокументировано, что выводится вновь выделенный объект или ссылка или копия одного, вызывающий объект отвечает за освобождение объекта, когда это будет сделано.

По соглашению функции с именем get0 возвращают невладеющие указатели. Функции с именами new или get1 возвращают владеющие указатели. Функции с именем set0 принимают владение аргументами. Функции с именем set1 — нет. Они обычно берут ссылку или делают копию внутри. Эти имена изначально относились к влиянию на счётчик ссылок, но соглашение в равной степени применимо к типам, не подсчитывающим ссылки.

Документация по API также может описывать более сложные обязательства. Например, объект может заимствовать указатель дольше, чем продолжительность одного вызова функции, в этом случае вызывающий объект должен обеспечить соответствующее продление времени жизни.

Ошибки памяти — одни из самых распространённых и опасных ошибок в C и C++, поэтому вызывающим объектам рекомендуется использовать такие инструменты, как AddressSanitizer и языки более высокого уровня.

Безопасность потоков

BoringSSL внутренне знает о библиотеке потоков платформы и вызывает её при необходимости. Обратитесь к документации по API для получения информации о гарантиях безопасности потоков конкретных объектов. В целом, объекты без состояния, такие как RSA или EVP_PKEY, которые представляют ключи, обычно можно использовать одновременно из нескольких потоков, если ни один поток не изменяет ключ.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/shike-boringssl.git
git@api.gitlife.ru:oschina-mirror/shike-boringssl.git
oschina-mirror
shike-boringssl
shike-boringssl
master