-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathmdm_vendor_sign.py
162 lines (131 loc) · 5.14 KB
/
mdm_vendor_sign.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env python
# This is based loosely on Softthinker's java code found here
# http://www.softhinker.com/in-the-news/iosmdmvendorcsrsigning
# fuck java
import argparse
from plistlib import writePlistToString
import os
import subprocess
from base64 import b64encode
import sys
import urllib2
def p(s):
sys.stdout.write(s)
sys.stdout.flush()
def mdm_vendor_sign():
"""
This utility will create a properly encoded certifiate signing request
that you can upload to identity.apple.com/pushcert
"""
parser = argparse.ArgumentParser(description=mdm_vendor_sign.__doc__)
parser.add_argument('--key', help='Private key', required=True)
parser.add_argument('--csr', help='Certificate signing request', required=True)
parser.add_argument('--mdm', help='MDM vendor certificate', required=True)
parser.add_argument('--out', help='Output filename', required=False)
cli_args = vars(parser.parse_args())
# Verify CSR
# openssl req -text -noout -verify -in CSR.csr
p('Verifying %s ... ' % cli_args['csr'])
csr_file = open(cli_args['csr']).read()
args = ['openssl', 'req', '-noout', '-verify' ]
command = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
output, error = command.communicate(input = csr_file)
if output.rstrip().split('\n')[0] == 'verify OK':
p('OK\n')
else:
p('FAILED\n')
return
# Verify private key
# openssl rsa -in privateKey.key -check
p('Verifying %s ... ' % cli_args['key'])
key_file = open(cli_args['key']).read()
args = ['openssl', 'rsa', '-check', '-noout' ]
command = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
output, error = command.communicate(input = key_file)
if output.rstrip().split('\n')[0] == 'RSA key ok':
p('OK\n')
else:
p('FAILED\n\n')
print """If you don't have the plain private key already, you need
to extract it from the pkcs12 file...
First convert to PEM
openssl pkcs12 -in filename.p12 -nocerts -out key.pem
Then export the certificate file from the pfx file
openssl pkcs12 -in filename.pfx -clcerts -nokeys -out cert.pem
Lastly Remove the passphrase from the private key
openssl rsa -in key.pem -out the_private_key.key
"""
return
# Verify MDM vendor certificate
# openssl x509 -noout -in mdm.cer -inform DER
p('Verifying %s ... ' % cli_args['mdm'])
mdm_cert_file = open(cli_args['mdm'],'rb').read() # Binary read
args = ['openssl', 'x509', '-noout', '-inform', 'DER' ]
command = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
output, error = command.communicate(input = mdm_cert_file)
if len(output) == 0:
p('OK\n')
else:
p('FAILED\n')
return
# Convert CSR to DER format
# openssl req -inform pem -outform der -in customer.csr -out customer.der
p('Converting %s to DER format... ' % cli_args['csr'])
args = ['openssl', 'req', '-inform', 'pem', '-outform', 'der' ]
command = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
output, error = command.communicate(input = csr_file)
if error:
p('FAILED\n')
return
p('OK\n')
csr_der = output
csr_b64 = b64encode(csr_der)
# Sign the CSR with the private key
# openssl sha1 -sign private_key.key -out signed_output.rsa data_to_sign.txt
p('Signing CSR with private key... ')
args = ['openssl', 'sha1', '-sign', cli_args['key'] ]
command = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
output, error = command.communicate(input = csr_der)
if error:
p('FAILED\n')
return
p('OK\n')
signature_bytes = output
signature = b64encode(signature_bytes)
def cer_to_pem(cer_data):
# openssl x509 -inform der -in mdm.cer -out mdm.pem
# -in and -out flags are handled by STDIN and STDOUT
args = ['openssl', 'x509', '-inform', 'der' ]
command = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
output, error = command.communicate(input = cer_data)
if error:
p('Error converting from cer to pem: %s' % error)
return output
# TODO : Probably should verify these too
p('Downloading WWDR intermediate certificate...')
intermediate_cer = urllib2.urlopen('https://developer.apple.com/certificationauthority/AppleWWDRCA.cer').read()
p(' converting to pem...')
intermediate_pem = cer_to_pem(intermediate_cer)
p('OK\n')
p('Downloading Apple Root Certificate...')
root_cer = urllib2.urlopen('http://www.apple.com/appleca/AppleIncRootCertificate.cer').read()
p(' converting to pem...')
root_pem = cer_to_pem(root_cer)
p('OK\n')
mdm_pem = cer_to_pem(mdm_cert_file)
p('Finishing...')
plist_dict = dict(
PushCertRequestCSR = csr_b64,
PushCertCertificateChain = mdm_pem + intermediate_pem + root_pem,
PushCertSignature = signature
)
plist_xml = writePlistToString(plist_dict)
plist_b64 = b64encode(plist_xml)
output_filename = cli_args['out'] if cli_args['out'] else 'plist_encoded'
write_path = os.path.join(os.getcwd(), output_filename)
output = open(write_path, 'wb')
output.write(plist_b64)
output.close()
p('DONE\n\nGo upload file \'%s\' to identity.apple.com/pushcert !\n' % output_filename)
if __name__=="__main__":
mdm_vendor_sign()