Created
February 20, 2014 21:19
-
-
Save aaronlevy/9123398 to your computer and use it in GitHub Desktop.
Test APNS PEM file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import socket | |
import ssl | |
import tempfile | |
from M2Crypto import RSA | |
from M2Crypto import X509 | |
from M2Crypto.util import no_passphrase_callback | |
SANDBOX_GATEWAY = 'gateway.sandbox.push.apple.com' | |
PRODUCTION_GATEWAY = 'gateway.push.apple.com' | |
class PemCheckError(Exception): pass | |
def test_pem(pem, sandbox=True): | |
gateway = SANDBOX_GATEWAY if sandbox else PRODUCTION_GATEWAY | |
pem_path = tempfile.mkstemp()[1] | |
with open(pem_path, 'w') as f: | |
f.write(pem) | |
try: | |
# Create the socket connection | |
try: | |
sock = ssl.wrap_socket( | |
socket.socket(socket.AF_INET, socket.SOCK_STREAM), | |
certfile=pem_path | |
) | |
sock.settimeout(.5) | |
sock.connect((gateway, 2195)) | |
except Exception as e: | |
raise PemCheckError("Error connecting to %s: %s" % (gateway, e)) | |
# Make sure the socket stays open (closes if wrong gateway) | |
try: | |
sock.recv() | |
# A closed socket will return empty string immediately | |
raise PemCheckError( | |
"Error connecting to %s: Socket connection closed." % gateway) | |
except ssl.SSLError as e: | |
# A timeout here means the connection is good | |
pass | |
finally: | |
sock.close() | |
os.remove(pem_path) | |
def process_pem(pem, password=None): | |
pw_cb = lambda *args: password if password else no_passphrase_callback | |
try: | |
certificate = X509.load_cert_string(pem).as_pem() | |
private_key = RSA.load_key_string(pem, pw_cb).as_pem(None) | |
return certificate + private_key | |
except Exception as e: | |
raise PemCheckError("Error decoding pem: %s" % e) | |
if __name__ == '__main__': | |
from optparse import OptionParser | |
import sys | |
parser = OptionParser(usage="USAGE: %prog [options] pem_path") | |
parser.add_option( | |
'-p', '--production', dest='sandbox', action='store_false', | |
default=True, help="use production gateway") | |
parser.add_option( | |
'-x', '--password', dest='password', metavar="PASS", | |
default=None, help="password to decrypt private key") | |
options, args = parser.parse_args() | |
if not args: | |
parser.print_help() | |
sys.exit(1) | |
orig_pem = open(args[0], 'r').read() | |
new_pem = process_pem(orig_pem, options.password) | |
test_pem(new_pem, options.sandbox) | |
print "SUCCESS" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment