Search code examples
objective-ccswiftopensslreceipt-validation

Use of unresolved identifier 'PKCS7_type_is_signed'


I'm writing the receipt validation code in swift, but I have a problem with a PKCS7_type_is_signed macro : Use of unresolved identifier 'PKCS7_type_is_signed'

Are there any way to use it in Swift except of creating Objective-C wrapper for this macros ?

Wrapper looks like this :

#import "OpenSSLWrapper.h"

#import "openssl/pkcs7.h"
#import "openssl/objects.h"

@implementation OpenSSLWrapper

+ (BOOL)PKCS7TypeIsSigned:(PKCS7*)bio{
    return PKCS7_type_is_signed(bio);
}

@end

Solution

  • From Apples Using Swift with Cocoa and Objective-C

    Complex macros are used in C and Objective-C but have no counterpart in Swift. Complex macros are macros that do not define constants, including parenthesized, function-like macros. You use complex macros in C and Objective-C to avoid type-checking constraints or to avoid retyping large amounts of boilerplate code. However, macros can make debugging and refactoring difficult. In Swift, you can use functions and generics to achieve the same results without any compromises. Therefore, the complex macros that are in C and Objective-C source files are not made available to your Swift code.

    And as pointed by nhgrif (thank you :-) ), 2 options here use wrapper or just expand macro.

    Expand Macro :

    # define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
    
    func PKCS7_type_is_signed(pkcs:UnsafeMutablePointer<PKCS7>)->Bool{
        return OBJ_obj2nid(pkcs.memory.type) == NID_pkcs7_signed
    }
    
    func PKCS7_type_is_data(pkcs:UnsafeMutablePointer<PKCS7>)->Bool{
        return (OBJ_obj2nid(pkcs.memory.type) == NID_pkcs7_data)
    }
    

    Wrapper :

    .h file:

    #import <Foundation/Foundation.h>
    #import "openssl/pkcs7.h"
    #import "openssl/objects.h"
    
        @interface OpenSSLWrapper:NSObject
        + (BOOL)PKCS7TypeIsSigned:(PKCS7*)bio;
        + (BOOL)PKCS7TypeIsData:(PKCS7*)contents;
        @end
    

    .m file :

    #import "OpenSSLWrapper.h"
    
    @implementation OpenSSLWrapper
    
    + (BOOL)PKCS7TypeIsSigned:(PKCS7*)bio{
        return PKCS7_type_is_signed(bio);
    }
    
    + (BOOL)PKCS7TypeIsData:(PKCS7*)contents{
        return PKCS7_type_is_data(contents);
    }
    
    
    @end