Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use of unresolved type X509 #9

Open
chamitha opened this issue Oct 4, 2018 · 9 comments
Open

Use of unresolved type X509 #9

chamitha opened this issue Oct 4, 2018 · 9 comments

Comments

@chamitha
Copy link

chamitha commented Oct 4, 2018

Hi there. I'm attempting to compile the ReceiptValidator in my project and running in to a few errors.
Use of undeclared type X509
Use of unresolved identifier OpenSSL_add_all_digests
Use of unresolved identifier c2i_ASN1_INTEGER - This has been raised and a workaround identified in a different thread so lets ignore it for now!

I'm using openssl 1.1.1 using a script similar to that in the OpenSSL pod. I have added the bridging header as per the demo project. My understanding is a module map is NOT required (as we are using bridging headers)?

Any assistance is most appreciated. Thanks!

@kamiro
Copy link

kamiro commented Dec 18, 2018

Just wanted to jump in on this thread and write how I fixed it.

I've been running around trying to figure out what happened to c2i_ASN1_INTEGER and it appears that in 2015 for OpenSSL 1.1.1 this method was moved into asn1_locl.h as a mechanism to hide it/make it private.
openssl/openssl@c315a54

I did not really research why this was moved, so one could use OpenSSL 1.1.0 or... one could re-expose this method by copying the missing function definition lines into my OpenSSL/include/openssl/asn1.h file to allow swift to have access to it (which was still built when compiling OpenSSL 1.1.1).

int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length);

@softmastx
Copy link

softmastx commented Jul 10, 2019

Just wanted to jump in on this thread and write how I fixed it.

I've been running around trying to figure out what happened to c2i_ASN1_INTEGER and it appears that in 2015 for OpenSSL 1.1.1 this method was moved into asn1_locl.h as a mechanism to hide it/make it private.
openssl/openssl@c315a54

I did not really research why this was moved, so one could use OpenSSL 1.1.0 or... one could re-expose this method by copying the missing function definition lines into my OpenSSL/include/openssl/asn1.h file to allow swift to have access to it (which was still built when compiling OpenSSL 1.1.1).

int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length);

By pasting int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length); into asn1.h that's it??

@kamiro
Copy link

kamiro commented Jul 10, 2019

Just wanted to jump in on this thread and write how I fixed it.
I've been running around trying to figure out what happened to c2i_ASN1_INTEGER and it appears that in 2015 for OpenSSL 1.1.1 this method was moved into asn1_locl.h as a mechanism to hide it/make it private.
openssl/openssl@c315a54
I did not really research why this was moved, so one could use OpenSSL 1.1.0 or... one could re-expose this method by copying the missing function definition lines into my OpenSSL/include/openssl/asn1.h file to allow swift to have access to it (which was still built when compiling OpenSSL 1.1.1).
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length);

By pasting int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length); into asn1.h that's it??

Pretty much. The method is still there, it just needs to be exposed... I still can't figure out why it was privatized. Copying that declaration into asn1.h and compiling solves the issue.

@itsryry
Copy link

itsryry commented Jul 14, 2019

any solutions for the x509 case?

@moldis
Copy link

moldis commented Nov 13, 2019

Any feedback on it ?

@thejeff77
Copy link

Fixed it up for 1.1.1d. I'll see if I can open a PR to update this project when I have time.

DecodeAS1Integer now becomes:

    func DecodeASN1Integer(startOfInt intPointer: inout UnsafePointer<UInt8>?, length: Int) -> Int? {
        let integer = d2i_ASN1_UINTEGER(nil, &intPointer, length)
        let result = ASN1_INTEGER_get(integer)
        ASN1_INTEGER_free(integer)
        
        return result
    }

Then OpenSSL_add_all_digests() becomes OPENSSL_init_crypto(UInt64(OPENSSL_INIT_ADD_ALL_DIGESTS), nil)

Then for the x509 issues in the ReceiptSignatureValidator, just combine the two internal methods - no need to separate them out and return an x509 type, just keep the result as a let constant and operate on it right away.

struct ReceiptSignatureValidator {
    func checkSignaturePresence(_ PKCS7Container: UnsafeMutablePointer<PKCS7>) throws {
        let pkcs7SignedTypeCode = OBJ_obj2nid(PKCS7Container.pointee.type)
        
        guard pkcs7SignedTypeCode == NID_pkcs7_signed else {
            throw ReceiptValidationError.receiptNotSigned
        }
    }
    
    func checkSignatureAuthenticity(_ PKCS7Container: UnsafeMutablePointer<PKCS7>) throws {
        try checkAppleRootCertificateAuthenticity(PKCS7Container: PKCS7Container)
    }
    
    fileprivate func checkAppleRootCertificateAuthenticity(PKCS7Container: UnsafeMutablePointer<PKCS7>) throws {
        guard
            let appleRootCertificateURL = Bundle.main.url(forResource: "AppleIncRootCertificate", withExtension: "cer"),
            let appleRootCertificateData = try? Data(contentsOf: appleRootCertificateURL)
            else {
                throw ReceiptValidationError.appleRootCertificateNotFound
        }
        
        let appleRootCertificateBIO = BIO_new(BIO_s_mem())
        BIO_write(appleRootCertificateBIO, (appleRootCertificateData as NSData).bytes, Int32(appleRootCertificateData.count))
        let appleRootCertificateX509 = d2i_X509_bio(appleRootCertificateBIO, nil)
        
        let x509CertificateStore = X509_STORE_new()
        X509_STORE_add_cert(x509CertificateStore, appleRootCertificateX509)
        
        OPENSSL_init_crypto(UInt64(OPENSSL_INIT_ADD_ALL_DIGESTS), nil)
        
        let result = PKCS7_verify(PKCS7Container, nil, x509CertificateStore, nil, nil, 0)
        
        if result != 1 {
            throw ReceiptValidationError.receiptSignatureInvalid
        }
    }
}

@tcherna
Copy link

tcherna commented Apr 4, 2020

Then OpenSSL_add_all_digests() becomes OPENSSL_init_crypto(UInt64(OPENSSL_INIT_ADD_ALL_DIGESTS), nil)

Isn't that no longer needed at all, since it is a default?

Also isn't there a memory free requirement on:
let appleRootCertificateX509 = d2i_X509_bio(appleRootCertificateBIO, nil)
Still trying to figure out which allocations need freeing.

@yousifKashef
Copy link

Hi Guys,

the reason these bugs come up in the ReceiptSignatureValidator class is because OpenSSL's X509 class, which contains the functionality used in ReceiptSignatureValidator is not imported in the bridging header. it can be imported by adding #import <openssl/x509.h> to the bridging header.h file. I hope this helps.

@diachedelic
Copy link

You can avoid using the c2i_ASN1_INTEGER function (and hence modifying asn1.h) by simply rewriting the DecodeASN1Integer function to use the d2i_* variant, which is exposed:

func DecodeASN1Integer(startOfInt intPointer: inout UnsafePointer<UInt8>?, length: Int) -> Int? {
    let integer = d2i_ASN1_UINTEGER(nil, &intPointer, length)
    let result = ASN1_INTEGER_get(integer)
    ASN1_INTEGER_free(integer)
    return result
}

Source: openssl/openssl#7538 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants