简体   繁体   中英

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

I'm working with OpenSSL and therefore am having to work with some UnsafeMutablePointer objects.

I'm running the following code

  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)

The above code converts an OpenSSL X509_REQ object into a DER using the OpenSSL method i2d_X509_REQ_bio . The problem I'm having is the BIO_read command and the UnsafeMutablePointer storage object both need a size count for the number of bytes. Does anybody know the correct way to get the length of bytes of an object pointed to by a UnsafeMutablePointer<Any> in Swift? (I'm hard-coding an arbitrary number right now, 3000, which is very bad) The X509_Req object doesn't have any size or count helper methods on it, and digging into Apple's documentation I'm not seeing a clear way to find the length of an object at a pointer.

A pointer is just a memory address, without any information of the size of the memory region that it points to.

However – if I understand the task correctly – what you actually need is the amount of bytes written to the memory-based BIO. That's what BIO_get_mem_data is for. Unfortunately, the OpenSSL library implements that as a macro

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

which is not imported into Swift, so that you have to call BIO_ctrl directly.

Example (error checking omitted for brevity):

// 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM