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 )