All pastes #2049002 Raw Edit

Unnamed

public text v1 · immutable
#2049002 ·published 2011-04-21 14:28 UTC
rendered paste body
#!/usr/bin/env python
#
#vim: ts=4 sw=4 nowrap
#


import M2Crypto
import time
import sys
import hashlib

CERT_PATH='/root/root-ca'

MBSTRING_FLAG = 0x1000
MBSTRING_ASC  = MBSTRING_FLAG | 1
MBSTRING_BMP  = MBSTRING_FLAG | 2


class Cert:
        def __init__ ( self ):
                self.RsaKey = { 'KeyLength'       : 1024,
                                'PubExponent'     : 0x10001,            # -> 65537
                                'keygen_callback' : self.callback
                              }

                self.KeyPair           = None
                self.PKey              = None

                self.X509Request       = None
                self.X509Certificate   = None

                self.X509CACertificate = None
                self.CAPKey            = None

        def callback ( self, *args ):
                return 'p'


        def CreatePKey ( self ):
                # Create a keypair for RSA magic
                self.KeyPair = M2Crypto.RSA.gen_key( self.RsaKey['KeyLength'], self.RsaKey['
PubExponent'], self.RsaKey['keygen_callback'] )

                self.PKey = M2Crypto.EVP.PKey ( md='sha1')
                # Set PKey to the RSA side of this keypair
                self.PKey.assign_rsa ( self.KeyPair )


        def CreateX509Request ( self, cn ):
                # Start X509 request
                self.X509Request = M2Crypto.X509.Request ()

                # Set up the subject

                X509Name = M2Crypto.X509.X509_Name ()

                X509Name.add_entry_by_txt ( field='C',            type=MBSTRING_ASC, entry='
US',                  len=-1, loc=-1, set=0 )    # country name
                X509Name.add_entry_by_txt ( field='ST',           type=MBSTRING_ASC, entry='
California',          len=-1, loc=-1, set=0 )    # state of province name
                X509Name.add_entry_by_txt ( field='L',            type=MBSTRING_ASC, entry='
Menlo Park',          len=-1, loc=-1, set=0 )    # locality name
                X509Name.add_entry_by_txt ( field='O',            type=MBSTRING_ASC, entry='Nevro',               len=-1, loc=-1, set=0 )    # organization name
                X509Name.add_entry_by_txt ( field='OU',           type=MBSTRING_ASC, entry='it-department',       len=-1, loc=-1, set=0 )    # organizational unit name
                X509Name.add_entry_by_txt ( field='CN',           type=MBSTRING_ASC, entry=cn,                    len=-1, loc=-1, set=0 )    # common name
                X509Name.add_entry_by_txt ( field='Email',        type=MBSTRING_ASC, entry='admin@nevro.com',     len=-1, loc=-1, set=0 )    # pkcs9 email address
                X509Name.add_entry_by_txt ( field='emailAddress', type=MBSTRING_ASC, entry='admin@nevro.com',     len=-1, loc=-1, set=0 )    # pkcs9 email address

                self.X509Request.set_subject_name( X509Name )

                # Assign it to the RSA publicKey

                self.X509Request.set_pubkey ( pkey=self.PKey )

                # Sign off on the fact that this publicKey is for this CSR
                self.X509Request.sign ( pkey=self.PKey, md='sha1' )






        def CreateX509Certificate ( self ):
                self.X509Certificate =  M2Crypto.X509.X509 ()
                self.X509Certificate.set_version ( 0 )

                t = long(time.time())
                # Set notBefore and notAfter for a 5-year cert
                ASN1 = M2Crypto.ASN1.ASN1_UTCTIME ()
                ASN1.set_time ( t )
                self.X509Certificate.set_not_before( ASN1 )

                ASN1 = M2Crypto.ASN1.ASN1_UTCTIME ()
                ASN1.set_time ( t + 60 * 60 * 24 * 365 * 5 ) # 5 years
                self.X509Certificate.set_not_after( ASN1 )

                # Assign it to the same RSA publicKey
                self.X509Certificate.set_pubkey ( pkey=self.PKey )

                # Set the CRT subject from the CSR
                X509Name = self.X509Request.get_subject ()
                self.X509Certificate.set_subject_name( X509Name )

                # Load the root CA/key
                self.X509CACertificate = M2Crypto.X509.load_cert(CERT_PATH + '/public/root.pem')
                self.CAPKey = M2Crypto.EVP.load_key(CERT_PATH + '/private/root.pem')

                # Set the root CA as the issuer
                self.X509Certificate.set_issuer( self.X509CACertificate.get_issuer() )
                ext1 = M2Crypto.X509.new_extension('basicConstraints', 'CA:FALSE')
                ext1.set_critical(1)
                modulus = self.PKey.get_modulus()
                sha_hash = hashlib.sha1(modulus).digest()
                sub_key_id = ":".join(["%02X"%ord(byte) for byte in sha_hash])

                ext2 = M2Crypto.X509.new_extension('subjectKeyIdentifier', sub_key_id)
                ext3 = M2Crypto.X509.new_extension('keyUsage',
               'Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment')
                ext3.set_critical(1)
                ext4 = self.X509CACertificate.get_ext('authorityKeyIdentifier')
                self.X509Certificate.add_ext(ext1)
                self.X509Certificate.add_ext(ext2)
                self.X509Certificate.add_ext(ext3)
                self.X509Certificate.add_ext(ext4)

                # Sign with the root CA's key
                self.X509Certificate.sign( pkey=self.CAPKey, md='sha1' )





if __name__ == '__main__':
        if len (sys.argv) < 2:
                sys.exit('Usage: %s any.domain-name.com' % sys.argv[0])
        run = Cert ()
        run.CreatePKey ()
        run.CreateX509Request (sys.argv[1])
        run.CreateX509Certificate ()

        # Save the cert
        run.X509Certificate.save( CERT_PATH + '/signed-certs/' + sys.argv[1] + '.crt')
        # Save the key without a passphrase (cipher = None)
        run.PKey.save_key( CERT_PATH + '/signed-certs/' + sys.argv[1] + '.key', cipher=None, callback=run.callback )