Skip to content

Instantly share code, notes, and snippets.

@espresso3389
Created December 10, 2024 18:41
Show Gist options
  • Save espresso3389/2ac067ea71ed7c85b1962dc42592c739 to your computer and use it in GitHub Desktop.
Save espresso3389/2ac067ea71ed7c85b1962dc42592c739 to your computer and use it in GitHub Desktop.
Get info. such as signing certificate's serial number from provisioning profile
#!/usr/bin/env ruby
require 'openssl'
def print_usage
puts "Usage: #{File.basename($0)} <provisioning_profile_path>"
puts "Example: #{File.basename($0)} /path/to/profile.mobileprovision"
exit 1
end
def extract_value(decoded_data, key)
pattern = /<key>#{key}<\/key>\s*<string>([^<]+)<\/string>/
decoded_data.match(pattern)&.captures&.first
end
def extract_cert_data(decoded_data)
pattern = /<key>DeveloperCertificates<\/key>\s*<array>\s*<data>([^<]+)<\/data>/m
decoded_data.match(pattern)&.captures&.first
end
# Check command line arguments
print_usage if ARGV.length != 1
profile_path = ARGV[0]
# Verify file exists
unless File.exist?(profile_path)
puts "Error: File not found: #{profile_path}"
exit 1
end
# Extract the embedded plist using security cms
begin
decoded_data = `security cms -D -i "#{profile_path}"`
if $?.success?
# Extract certificate data and convert from base64
if cert_base64 = extract_cert_data(decoded_data)
cert_data = cert_base64.unpack('m')[0]
cert = OpenSSL::X509::Certificate.new(cert_data)
serial_number = cert.serial.to_s(16).upcase
end
# Extract other required information
uuid = extract_value(decoded_data, 'UUID')
name = extract_value(decoded_data, 'Name')
team_name = extract_value(decoded_data, 'TeamName')
# The application-identifier is nested in Entitlements
app_id_pattern = /<key>Entitlements<\/key>.*?<key>application-identifier<\/key>\s*<string>([^<]+)<\/string>/m
if app_id = decoded_data.match(app_id_pattern)&.captures&.first
# Split application-identifier into team ID and bundle ID
team_id, bundle_id = app_id.split('.', 2)
end
if serial_number && uuid
puts "PP_SN=#{serial_number}"
puts "PP_UUID=#{uuid}"
puts "PP_NAME=\"#{name}\""
puts "PP_TEAM_ID=#{team_id}"
puts "PP_APP_ID=#{bundle_id}"
puts "PP_TEAM_NAME=\"#{team_name}\""
else
puts "Error: Failed to extract required information from the provisioning profile"
end
else
puts "Error: Failed to decode the provisioning profile"
puts decoded_data if ENV['DEBUG']
end
rescue StandardError => e
puts "Error: #{e.message}"
puts e.backtrace if ENV['DEBUG']
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment