Skip to content

Instantly share code, notes, and snippets.

@vfig
Last active August 29, 2015 14:13
Show Gist options
  • Save vfig/ad15ff7a70b0d5647bc2 to your computer and use it in GitHub Desktop.
Save vfig/ad15ff7a70b0d5647bc2 to your computer and use it in GitHub Desktop.
Display a list of provisioning profiles with at least one valid code-signing identity.
#!/usr/bin/python2.7
## Display a list of provisioning profiles with at least one valid code-signing identity.
##
## Displays the UUID and app identifier for each such provisioning profile, followed by the
## fingerprint and name of the matching code-signing identities.
import glob, os, plistlib, re, subprocess
PROVISIONING_PROFILES_DIR = os.path.expanduser('~/Library/MobileDevice/Provisioning Profiles')
OPENSSL = '/usr/bin/openssl'
SECURITY = '/usr/bin/security'
def profile_find():
return glob.glob(os.path.join(PROVISIONING_PROFILES_DIR, '*.mobileprovision'))
def profile_extract_plist(profile_path):
return subprocess.check_output([SECURITY, 'cms', '-D', '-i', profile_path])
def plist_get_uuid(plist_xml):
plist = plistlib.readPlistFromString(plist_xml)
return plist["UUID"]
def plist_get_application_identifier(plist_xml):
plist = plistlib.readPlistFromString(plist_xml)
return plist["Entitlements"]["application-identifier"]
def plist_iter_certificates(plist_xml):
plist = plistlib.readPlistFromString(plist_xml)
for cert in plist["DeveloperCertificates"]:
yield cert.data
def codesigning_find_identities():
output = subprocess.check_output([SECURITY, 'find-identity', '-v', '-p', 'codesigning'])
for line in output.splitlines():
if 'REVOKED' in line: continue
match = re.search(r'(?P<sha>(?:[0-9A-Fa-f][0-9A-Fa-f]){20}) "(?P<name>[^"]+)"', line)
if match:
yield match.group('sha'), match.group('name')
def plist_filter_certificates(plist, identities):
for cert in plist_iter_certificates(plist):
sha = certificate_get_sha(cert)
if sha in identities:
yield sha, identities[sha]
def certificate_get_sha(certificate_data):
args = [OPENSSL, 'x509', '-inform', 'der', '-noout', '-sha1', '-fingerprint']
p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate(certificate_data)
match = re.search(r'(?:[0-9A-Fa-f][0-9A-Fa-f]:?){20}', stdout)
if not match:
raise ValueError("Could not find fingerprint in %r" % stdout)
fingerprint = match.group(0).replace(':', '')
return fingerprint
def main():
identities = dict(codesigning_find_identities())
for profile in profile_find():
plist = profile_extract_plist(profile)
certs = list(plist_filter_certificates(plist, identities))
if not certs: continue
print plist_get_uuid(plist), plist_get_application_identifier(plist)
for sha, identity in certs:
print " ", sha, identity
print
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment