import subprocess import sys import zipfile import bs4 import base64 if len(sys.argv) != 3: print('Invalid number of arguments.') exit(1) ipa = sys.argv[1] app_name = ipa.split('/')[-1].split('.')[0] cert = sys.argv[2] workspace = '/'.join(sys.argv[1].split('/')[0:-1]) provfile = workspace + '/Payload/' + app_name + '.app/embedded.mobileprovision' # Unzip the IPA file with zipfile.ZipFile(ipa, 'r') as ipa_file: ipa_file.extractall(workspace) get_prov = subprocess.Popen(['security', 'cms', '-Di', provfile], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) provxml = ''.join(map(lambda x: str(x, 'utf-8'), get_prov.stdout.readlines())) def base64ify(fn): with open(fn, 'rb') as f: return str(base64.b64encode(f.read()), 'utf-8') # Parse doc to get cert base64 string soup = bs4.BeautifulSoup(provxml, 'html.parser') certs = None exp_date = None for k in soup('key'): if k.string == 'DeveloperCertificates': certs = [x.string for x in k.findNext('array').findAll('data')] if k.string == 'ExpirationDate': exp_date = k.findNext('date').string # Decode cert and compare to specified cert refcert = base64ify(cert) for i, cer in enumerate(certs): if cer == refcert: print('Certificate (' + str(i + 1) + ') beginning: ' + cer[0: 9] + '... matches the specified certificate: ' + cert) if exp_date is not None: print('This provisioning profile expires on: ' + exp_date) else: print('the provisioning profiles expiration date could not be parsed.') print('The cert checker has finished.')