def create_certificate(self): """ Create Node certificate from Cluster CA authority """ if self.certificate is None: # Get PKI next serial number cluster = Cluster.objects.get() serial = cluster.ca_serial serial += 1 crt, key = ssl_utils.mk_signed_cert(ssl_utils.get_ca_cert_path(), ssl_utils.get_ca_key_path(), self.name, 'FR', '', '', '', '', serial) # TODO: Error handling # Save serial number cluster.ca_serial = serial cluster.save() # Store the certificate certificate = SSLCertificate() certificate.name = str(crt.get_subject()) certificate.cn = str(self.name) certificate.o = 'FR' certificate.cert = crt.as_pem().decode('utf8') certificate.key = key.as_pem(cipher=None).decode('utf8') certificate.status = 'V' certificate.issuer = str(crt.get_issuer()) certificate.validfrom = str(crt.get_not_before().get_datetime()) certificate.validtill = str(crt.get_not_after().get_datetime()) certificate.serial = str(serial) certificate.is_ca = False internal = cluster.ca_certificate certificate.chain = str(internal.cert) certificate.save() self.certificate = certificate self.save()
def sign(request): """ method dedicated to sign an external certificate request :param request: Django POST request object :param POST['csr']: The PEM certificate request """ cert = SSLCertificate() cert.cert = "" cert.key = "" cert.chain = "" cert.csr = "" if request.method == 'POST': dataPosted = request.POST error = dict() err = None try: cert.csr = str(dataPosted['csr']) except: err = True error['csr'] = "PEM Certificate request required" pass if err: return render_to_response('cert_sign.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # Check the request try: x509Request = X509.load_request_string(cert.csr) except: error['csr'] = "Invalid PEM Certificate Request" return render_to_response('cert_sign.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # Get cluster cluster = Cluster.objects.get() # Find the internal CA's certificate and private key internal = cluster.ca_certificate ca_key = RSA.load_key_string(internal.key.encode('utf8')) ca_cert = X509.load_cert_string(internal.cert.encode('utf8')) # Get PKI next serial number serial = cluster.ca_serial serial += 1 # Create a certificate from the request crt = mk_cert(serial) crt.set_pubkey(x509Request.get_pubkey()) pk = EVP.PKey() pk.assign_rsa(ca_key) issuer = X509.X509_Name() subject = X509.X509_Name() fields = str(x509Request.get_subject()).split('/') for field in fields: tmp = field.split('=') if str(tmp[0]) == "CN": subject.CN = tmp[1] cert.cn = tmp[1] elif str(tmp[0]) == "C": subject.C = tmp[1] cert.c = tmp[1] elif str(tmp[0]) == "ST": subject.ST = tmp[1] cert.st = tmp[1] elif str(tmp[0]) == "L": subject.L = tmp[1] cert.l = tmp[1] elif str(tmp[0]) == "O": subject.O = tmp[1] cert.o = tmp[1] elif str(tmp[0]) == "OU": subject.OU = tmp[1] cert.ou = tmp[1] fields = str(ca_cert.get_subject()).split('/') for field in fields: tmp = field.split('=') if str(tmp[0]) == "CN": issuer.CN = tmp[1] elif str(tmp[0]) == "C": issuer.C = tmp[1] elif str(tmp[0]) == "ST": issuer.ST = tmp[1] elif str(tmp[0]) == "L": issuer.L = tmp[1] elif str(tmp[0]) == "O": issuer.O = tmp[1] elif str(tmp[0]) == "OU": issuer.OU = tmp[1] crt.set_subject(subject) crt.set_issuer(issuer) crt.add_ext(X509.new_extension('basicConstraints', 'CA:FALSE')) crt.add_ext( X509.new_extension('subjectKeyIdentifier', str(crt.get_fingerprint()))) try: crt.sign(pk, 'sha256') except Exception as e: print(e) # Save serial number cluster.ca_serial = serial cluster.save() # Store the certificate cert.cert = crt.as_pem().decode('utf8') cert.name = str(crt.get_subject()) cert.status = 'V' cert.issuer = str(internal.issuer) cert.validfrom = str(crt.get_not_before().get_datetime()) cert.validtill = str(crt.get_not_after().get_datetime()) cert.is_ca = False cert.chain = str(internal.cert) cert.serial = str(serial) cert.save() return HttpResponseRedirect('/system/cert/') return render_to_response('cert_sign.html', { 'cert': cert, }, context_instance=RequestContext(request))
def load(request): """ method dedicated to certificate importation :param request: Django POST request object :param POST['cert']: The PEM X509 certificate :param POST['key']: The PEM X509 key :param POST['chain']: The PEM X509 certificate chain """ cert = SSLCertificate() cert.cert = "" cert.key = "" cert.chain = "" if request.method == 'POST': dataPosted = request.POST error = dict() err = None try: cert_cert = dataPosted['cert'] except: err = True error['cert'] = "X509 PEM Certificate required" pass try: cert_key = dataPosted['key'] except: err = True error['key'] = "X509 PEM Key required" pass try: cert.chain = str(dataPosted['chain']) except: pass if err: return render_to_response('cert_import.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # Check the certificate try: x509Cert = X509.load_cert_string(bytes(cert_cert, 'utf8')) cert.cert = str(cert_cert) except: error['cert'] = "Invalid X509 PEM Certificate" return render_to_response('cert_import.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) global keypass try: keypass = str(dataPosted['keypass']) except: pass # Check the private key try: bio = BIO.MemoryBuffer(bytes(cert_key, 'utf8')) RSA.load_key_bio(bio, callback=read_pass_from_POST) cert.key = str(cert_key) except RSA.RSAError: try: bio = BIO.MemoryBuffer(bytes(cert_key, 'utf8')) EC.load_key_bio(bio, callback=read_pass_from_POST) cert.key = str(cert_key) except RSA.RSAError: error['keypass'] = "******" except Exception as e: logger.exception(e) error['key'] = "Invalid PEM KEY" except Exception as e: logger.exception(e) error['key'] = "Invalid PEM KEY" if error: return render_to_response('cert_import.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # Store certificate details cert.name = str(x509Cert.get_subject()) cert.status = 'V' cert.issuer = str(x509Cert.get_issuer()) try: cert.validfrom = str(x509Cert.get_not_before().get_datetime()) except Exception as e: logger.error( "Exception while retrieving validation date 'before' of certificates : " ) logger.exception(e) try: cert.validtill = str(x509Cert.get_not_after().get_datetime()) except Exception as e: logger.error( "Exception while retrieving validation date 'after' of certificates : " ) logger.exception(e) if x509Cert.check_ca(): cert.is_ca = True else: cert.is_ca = False # Find certificate fields fields = cert.name.split('/') for field in fields: tmp = field.split('=') if str(tmp[0]) == "CN": cert.cn = tmp[1] elif str(tmp[0]) == "C": cert.c = tmp[1] elif str(tmp[0]) == "ST": cert.st = tmp[1] elif str(tmp[0]) == "L": cert.l = tmp[1] elif str(tmp[0]) == "O": cert.o = tmp[1] elif str(tmp[0]) == "OU": cert.ou = tmp[1] # if cert.cn is empty check if subjectAltName is set en use it if (not cert.cn): alt_name = x509Cert.get_ext('subjectAltName').get_value() if (alt_name): cert.cn = alt_name cert.save() return HttpResponseRedirect('/system/cert/') return render_to_response('cert_import.html', { 'cert': cert, }, context_instance=RequestContext(request))