Как предотвратить фатальные ошибки от неправильного ввода в d2i_X509_REQ_bio в Swift с OpenSSL - PullRequest
3 голосов
/ 05 апреля 2019

Контекст:

У меня есть следующий код, который загружает данные в BIO, а затем получает запрос X509:

    let reqBIO = BIO_new(BIO_s_mem())
    let result = BIO_write(reqBIO, (reqData as NSData).bytes, Int32(reqData.count))
    let x509ReqContainer: UnsafeMutablePointer<X509_REQ> = d2i_X509_REQ_bio(reqBIO, nil)
    BIO_free(reqBIO) 

Этот код отлично работает, когда вводЗакодированный в base64 DER, как и ожидалось.Однако, если я пропущу строку мусора, закодированную в base64, она взорвется, что приведет к фатальной ошибке.

Итак, мои вопросы:

  1. Есть ли какой-нибудь метод в OpenSSL, который я могу вызвать, который позволит мне определить, безопасно ли отправлять BIO в функцию d2i, чтобы я мог потерпеть неудачуизящно в этих случаях
  2. Есть ли способ отловить fatalError в swift?(Наверное, нет)
  3. Есть ли другой способ проверить, что моя строка base64 содержит CSR

1 Ответ

5 голосов
/ 05 апреля 2019

Короткая версия: d2i_X509_REQ_bio() не «выдает ошибку» при неверном вводе.Он просто возвращает нулевой указатель.Что приводит к сбою, так это то, что вы (возможно, непреднамеренно) принудительно разворачиваете дополнительный файл в Swift.

Более длинная версия: Функция C

X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x);

возвращает нулевой указатель на неверный ввод.Эта функция C отображается на Swift как

func d2i_X509_REQ_bio(...) -> UnsafeMutablePointer<X509_REQ>!

с «неявно развернутым необязательным» (IUO) в качестве возвращаемого типа, а нулевой указатель представляется как nil.IUO почти эквивалентен «нормальному» (сильному) необязательному, с той лишь разницей, что он принудительно разворачивается, если этого требует средство проверки типов.И это то, что происходит при присваивании

let x509ReqContainer: UnsafeMutablePointer<X509_REQ> = d2i_X509_REQ_bio(reqBIO, nil)

, поскольку переменная объявлена ​​как необязательная. Если функция C возвращает нулевой указатель из-за неверного ввода, тогда Swift Optional.nil распаковывается, и программа завершается с ошибкой во время выполнения.

Решение: Используйте необязательное связывание с if let (или guard let) и позвольте компилятору автоматически определить тип:

if let x509ReqContainer = d2i_X509_REQ_bio(reqBIO, nil) {
    // success ...
} else {
    // failed ...
}

Примечание: Вы можете написать Data в BIO с помощью

let result = reqData.withUnsafeBytes {
    BIO_write(reqBIO, $0.baseAddress, Int32($0.count))
}

вместо приведения его к NSData.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...