ValidateStoreReceipt icon indicating copy to clipboard operation
ValidateStoreReceipt copied to clipboard

Lion

Open kgn opened this issue 13 years ago • 4 comments

There are lots of deprecated warning under Lion: http://cl.ly/8f1r

kgn avatar Jul 22 '11 04:07 kgn

Ouch! This looks like a lot of work. But I will have a look.

roddi avatar Jul 22 '11 10:07 roddi

running lion and Xcode 4.2 this doesn't compile due to quite a few deprecated (and apparently completely removed) code.

Undefined symbols for architecture x86_64: "_ERR_load_PKCS7_strings", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_ERR_load_X509_strings", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_OpenSSL_add_all_digests", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_d2i_PKCS7_fp", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_OBJ_obj2nid", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_PKCS7_free", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_X509_STORE_new", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_d2i_X509", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_BIO_s_mem", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_BIO_new", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_X509_STORE_add_cert", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_PKCS7_verify", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_BIO_free", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_X509_free", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_X509_STORE_free", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_EVP_cleanup", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_ASN1_get_object", referenced from: _dictionaryWithAppStoreReceipt in validatereceipt.o "_SHA1", referenced from: _validateReceiptAtPath in validatereceipt.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

eblu avatar Nov 30 '11 19:11 eblu

Now that Mountain Lion is out it'd be great to use non-depricated calls.

kgn avatar Jul 29 '12 22:07 kgn

Hi, thanks for the example code and hopefully I can return the favour as I've just finished upgrading this code to sort all the deprecated warnings.

The OpenSSL ones can be dealt with by statically linking OpenSSL. This is simple as long as you do the following when you download and build OpenSSL locally (just from the command line): (1) Set your project Architecture to 32 bit or 64 bit (not both and build active arch only) and build OpenSSL for the same architecture (2) Rename the locally built libssl.a and lib crypto.a to slightly different names (add formac on the end was my preference) and then add -lsslformac -lcryptoformac in the Other Linker flags and add the local OpenSSL directory to the header and library search paths. This gets around XCode getting confused and linking to the dynamic libs

There are 4 Security library bits that also got deprecated in the code getting the Apple Root CA. If you replace everything after the keychain open with the code below then it does the same thing using alternate library functions available from 10.6 onwards.

Based on testing but with little help from the very sparse documentation on the Apple side (wouldn't it be really helpful when deprecating something to suggest the alternative!!!), this all seems to work:

char theA = 'A';
char thep = 'p';
char theC = 'C';
char theSpace = ' ';
char theR = 'R';
char thee = 'e';
char theo = 'o';
char thel = 'l';
char thet = 't';

// Cunning way of putting together the string Apple Root CA which is the cert we are looking for
NSString *certName = [NSString stringWithFormat:@"%3$c%2$c%2$c%1$c%7$c%9$c%8$c%4$c%4$c%5$c%9$c%6$c%3$c",
                      thel, thep, theA, theo, thet, theC, thee, theR, theSpace];

// And need to put into a CFString for use in the query
CFStringRef certLabel = CFStringCreateWithCString(NULL, [certName UTF8String],
                                                  kCFStringEncodingUTF8);

// Specific search for root CA certificate in this chain
NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
                       kSecClassCertificate, kSecClass,
                       [NSArray arrayWithObject:(id)keychain], kSecMatchSearchList,
                       certLabel, kSecAttrLabel,
                       kCFBooleanTrue, kSecReturnRef,
                       kCFBooleanTrue, kSecMatchTrustedOnly,        // Ensure only trusted certificates included
                       nil];

CFTypeRef certificateRef = NULL;
status = SecItemCopyMatching((CFDictionaryRef)query, &certificateRef);
if (status)
{
    return nil;
}

// At this point should have a single certificate reference
if(certificateRef == NULL)
{
    return nil;
}

// And we need to get the DER representation of the certificate for use by OpenSSL
CFDataRef certData;
NSData * resultData;
certData = SecCertificateCopyData((SecCertificateRef)certificateRef);

// Copy the data into a new buffer and free up the original
resultData = [NSData dataWithBytes:CFDataGetBytePtr(certData) length:CFDataGetLength(certData)];
CFRelease(certData);

return resultData;

worsfolg007 avatar Oct 21 '12 17:10 worsfolg007