How to solve this error 'BIO_new' is depre

2019-05-29 10:30发布

问题:

I am new to Macintosh development. I have NSData+connection.m file. This file have more deprecated function like BIO_new , BIO_write, BIO_get_mem_data etc. The functions all encounter deprecated errors.

- (NSString *)base64Encoding
{
    BIO * mem = BIO_new(BIO_s_mem());
    BIO * b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    mem = BIO_push(b64, mem);

    BIO_write(mem, [self bytes], [self length]);
    BIO_flush(mem);

    char * base64Pointer;
    long base64Length = BIO_get_mem_data(mem, &base64Pointer);

    NSString * base64String = [NSString stringWithCString:base64Pointer
                                               length:base64Length];

    BIO_free_all(mem);
    return base64String;
}

Please help me.

回答1:

What Apple has deprecated is using their OpenSSL headers and their OpenSSL dynamic library. The reason is that OpenSSL's interface changes in incompatible ways even across minor revisions, so it's hard to keep up to date with bugfixes and security updates without breaking client code.

What you can do (and what I have done in the past) is grab OpenSSL yourself, use the functions from that version and bundle that with your application.



回答2:

If your application targets Mac OS X 10.7 or higher, you could use SecTransform instead.

Worth noting as well that base64 has quite a few variants (the Wikipedia article lists no fewer than 13), which might make you wary of using other peoples' implementations of it unless they properly document their behaviour (IMO both OpenSSL and SecTransform fail to fully specify their behaviour in their documentation).



回答3:

How to solve this error 'BIO_new' is deprecated in cocoa?

You solve this issue by not using Apple's version of OpenSSL located in /usr/include and /usr/lib. Its an old version - 0.9.8 - so its missing a number of features. Its loss will not be missed.

Instead, you should download, build and install the latest version of OpenSSL. You can download it from OpenSSL: Source, Tarballs.

Configure with the following (there's a more comprehensive list of options on the OpenSSL wiki at Configure Options).

$ export KERNEL_BITS=64
$ ./config no-ssl2 enable-ec_nistp_64_gcc_128 --openssldir=/usr/local
$ make all
$ sudo make install

--openssldir=/usr/local means /usr/local/ssl will be the base directory for the installation.

Later, when you compile and link, you perform the following:

  • Add /usr/local/ssl/include ans a header search path (i.e., a -I option)
  • Add /usr/local/ssl/lib ans a library search path (i.e., a -L option)

If you use -L, then be sure to use DYLD_LIBRARY_PATH when executing your program. Its like LD_PRELOAD on Linux. If you don't use DYLD_LIBRARY_PATH, then dyld will load the old, 0.9.8 version of OpenSSL located in /usr/lib; and not your updated, 1.0.1 version of OpenSSL located in /usr/local/ssl/lib/.

Better, omit -L and specify the full library paths.

  • /usr/local/ssl/lib/libssl.a
  • /usr/local/ssl/lib/libcrypto.a

This way you don't need to worry about -L and DYLD_LIBRARY_PATH. Things just work as expected.