如何在 Swift 中获取写入 OpenSSL BIO 的 UnsafeMutablePointer<Object> 的长度?

How to get length of a UnsafeMutablePointer<Object> written to a OpenSSL BIO in Swift?

我正在使用 OpenSSL,因此必须使用一些 UnsafeMutablePointer 对象。

我是运行下面的代码

  var x509_REQ : UnsafeMutablePointer<X509_REQ> = someObject
  let b = BIO_new(BIO_s_mem())
  let size = 3000

  let status = i2d_X509_REQ_bio(b, x509_REQ)

  guard status == 1 else{
        BIO_free(b)
        return "Failed to execute i2d_X509_REQ_bio command"
  }

  let bp = UnsafeMutableRawPointer.allocate(byteCount: size, alignment: 1)
  BIO_read(b, bp, Int32(size))
  BIO_free(b)

  let data = Data(bytes: bp, count: size)

以上代码使用 OpenSSL 方法 i2d_X509_REQ_bio 将 OpenSSL X509_REQ 对象转换为 DER。我遇到的问题是 BIO_read 命令和 UnsafeMutablePointer 存储对象都需要字节数的大小计数。有人知道获取 Swift 中的 UnsafeMutablePointer<Any> 指向的对象的字节长度的正确方法吗? (我现在正在硬编码一个任意数字,3000,这是非常糟糕的)X509_Req 对象没有任何 sizecount 辅助方法,并且挖掘在 Apple 的文档中,我没有看到一种明确的方法来查找指针处对象的长度。

指针只是一个内存地址,没有任何它指向的内存区域大小的信息。

但是——如果我理解正确的话——你真正需要的是写入基于内存的 BIO 的字节数。这就是 BIO_get_mem_data 的用途。不幸的是,OpenSSL 库将其实现为宏

# define BIO_get_mem_data(b,pp)  BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)

未导入到 Swift,因此您必须直接调用 BIO_ctrl

示例(为简洁起见省略了错误检查):

// Create memory-based BIO:
let membio = BIO_new(BIO_s_mem())

// Write to BIO:
let status = i2d_X509_REQ_bio(membio, x509_REQ)

// Get pointer to the start of the memory BIOs data
// and amount of data available:
var ptr: UnsafeMutableRawPointer?
let len = BIO_ctrl(membio, BIO_CTRL_INFO, 0, &ptr)

// Create `Data` object from that memory region:
let data = Data(bytes: ptr!, count: len)

// Release BIO:
BIO_vfree(membio)