[cert_utils] Des fonction pour manipuler des certificats/csr
This commit is contained in:
parent
52cddb38c4
commit
71109c083b
1 changed files with 201 additions and 0 deletions
201
gestion/cert_utils.py
Normal file
201
gestion/cert_utils.py
Normal file
|
@ -0,0 +1,201 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from OpenSSL import crypto, SSL
|
||||
from socket import gethostname
|
||||
from pprint import pprint
|
||||
import time
|
||||
from os.path import exists, join
|
||||
|
||||
def crt_import(str):
|
||||
return crypto.load_certificate(crypto.FILETYPE_PEM, open(str).read())
|
||||
|
||||
def key_import(str):
|
||||
return crypto.load_privatekey(crypto.FILETYPE_PEM, open(str).read())
|
||||
|
||||
def crt_write(crt, file):
|
||||
open(file, "wt").write(
|
||||
crypto.dump_certificate(crypto.FILETYPE_PEM, crt))
|
||||
|
||||
def key_write(key, file, cipher=None, passphrase=None):
|
||||
open(file, "wt").write(
|
||||
crypto.dump_privatekey(crypto.FILETYPE_PEM, key, cipher, passphrase) if cipher else crypto.dump_privatekey(crypto.FILETYPE_PEM, key))
|
||||
|
||||
def write((cert, key), cert_dir="."):
|
||||
common_name = cert.get_subject().CN
|
||||
CERT_FILE = "%s.crt" % common_name
|
||||
KEY_FILE = "%s.key" % common_name
|
||||
C_F = join(cert_dir, CERT_FILE)
|
||||
K_F = join(cert_dir, KEY_FILE)
|
||||
if not exists(C_F) or not exists(K_F):
|
||||
crt_write(cert,C_F)
|
||||
key_write(key,K_F)
|
||||
else:
|
||||
print "Les fichiers %s et %s existent déjà" % (C_F, K_F)
|
||||
|
||||
def crl_gen(crl=None, add_crt=[]):
|
||||
if not crl:
|
||||
crl=crypto.CRL()
|
||||
for crt in add_crt:
|
||||
revoked = crypto.Revoked()
|
||||
revoked.set_serial(hex(crt.get_serial_number()))
|
||||
crl.add_revoked(revoked)
|
||||
return crl
|
||||
|
||||
def crl_export(crl, (ca_cert, ca_key)):
|
||||
return crl.export(ca_cert, ca_key)
|
||||
|
||||
def crt_create(
|
||||
common_name,
|
||||
params={},
|
||||
not_after=365*24*3600,
|
||||
size=4096,
|
||||
key=None,
|
||||
parent=None,
|
||||
extentions=[]
|
||||
):
|
||||
"""
|
||||
@param parent: tuple (X509 certificate, private key)
|
||||
@return: (X509 certificate, private key)
|
||||
"""
|
||||
params["CN"] = common_name # common name
|
||||
params.setdefault("C", "FR") # country
|
||||
params.setdefault("ST", "Val de Marne") # state
|
||||
params.setdefault("L", "Cachan") # city
|
||||
params.setdefault("O", "Association CRANS") # organization
|
||||
params.setdefault("OU", "") # organization unit
|
||||
|
||||
if not key:
|
||||
# create a key pair
|
||||
k = crypto.PKey()
|
||||
k.generate_key(crypto.TYPE_RSA, size)
|
||||
else:
|
||||
k = key
|
||||
if k.bits() != size:
|
||||
raise ValueError("Key of %s bits but requesting %s bits" % (k.bits, size))
|
||||
|
||||
# create a certificate
|
||||
cert = crypto.X509()
|
||||
cert.get_subject().C = params["C"]
|
||||
cert.get_subject().ST = params["ST"]
|
||||
cert.get_subject().L = params["L"]
|
||||
cert.get_subject().O = params["O"]
|
||||
if params["OU"]:
|
||||
cert.get_subject().OU = params["OU"]
|
||||
cert.get_subject().CN = params["CN"]
|
||||
|
||||
cert.set_serial_number(int((time.time() - 1386340000)*100))
|
||||
cert.gmtime_adj_notBefore(0)
|
||||
cert.gmtime_adj_notAfter(not_after)
|
||||
cert.set_pubkey(k)
|
||||
cert.add_extensions(extentions)
|
||||
if parent:
|
||||
cert.set_issuer(parent[0].get_subject())
|
||||
cert.sign(parent[1], 'sha1')
|
||||
else:
|
||||
cert.set_issuer(cert.get_subject())
|
||||
cert.sign(k, 'sha1')
|
||||
|
||||
return (cert, k)
|
||||
|
||||
|
||||
def crt_ca_root_create(
|
||||
common_name,
|
||||
params={},
|
||||
size=4096,
|
||||
key=None,
|
||||
not_after=365*24*3600*10,
|
||||
):
|
||||
extentions=[
|
||||
crypto.X509Extension("basicConstraints", True, "CA:TRUE"),
|
||||
crypto.X509Extension("keyUsage", True, "keyCertSign, cRLSign"),
|
||||
]
|
||||
return crt_create(
|
||||
common_name,
|
||||
params,
|
||||
not_after,
|
||||
size,
|
||||
key,
|
||||
extentions=extentions
|
||||
)
|
||||
|
||||
|
||||
def crt_ca_subroot_create(
|
||||
common_name,
|
||||
parent,
|
||||
params={},
|
||||
size=4096,
|
||||
key=None,
|
||||
not_after=365*24*3600*10,
|
||||
):
|
||||
extentions=[
|
||||
crypto.X509Extension("basicConstraints", True, "CA:TRUE, pathlen:0"),
|
||||
crypto.X509Extension("keyUsage", True, "keyCertSign, cRLSign"),
|
||||
]
|
||||
return crt_create(
|
||||
common_name,
|
||||
params,
|
||||
not_after,
|
||||
size,
|
||||
key,
|
||||
parent=parent,
|
||||
extentions=extentions
|
||||
)
|
||||
|
||||
def crt_client_create(
|
||||
common_name,
|
||||
parent,
|
||||
params={},
|
||||
size=4096,
|
||||
key=None,
|
||||
not_after=365*24*3600,
|
||||
alt_names=[]
|
||||
):
|
||||
extentions=[
|
||||
crypto.X509Extension("basicConstraints", True, "CA:FALSE"),
|
||||
crypto.X509Extension("keyUsage", True, "digitalSignature, nonRepudiation, keyEncipherment"),
|
||||
crypto.X509Extension("nsCertType", True, "sslCA"),
|
||||
crypto.X509Extension("extendedKeyUsage", True, "clientAuth"),
|
||||
# crypto.X509Extension("crlDistributionPoints", False, "URI:http://myhost.com/myca.crl"),
|
||||
]
|
||||
for name in alt_names:
|
||||
extentions.append(crypto.X509Extension("subjectAltName", True, "%s" % name))
|
||||
return crt_create(
|
||||
common_name,
|
||||
params,
|
||||
not_after,
|
||||
size,
|
||||
key,
|
||||
parent=parent,
|
||||
extentions=extentions
|
||||
)
|
||||
|
||||
|
||||
def createCertRequest(pkey, digest="sha1", subjectAltName=[], **name):
|
||||
"""
|
||||
Create a certificate request.
|
||||
Arguments: pkey - The key to associate with the request
|
||||
digest - Digestion method to use for signing, default is md5
|
||||
**name - The name of the subject of the request, possible
|
||||
arguments are:
|
||||
C - Country name
|
||||
ST - State or province name
|
||||
L - Locality name
|
||||
O - Organization name
|
||||
OU - Organizational unit name
|
||||
CN - Common name
|
||||
emailAddress - E-mail address
|
||||
Returns: The certificate request in an X509Req object
|
||||
"""
|
||||
req = crypto.X509Req()
|
||||
subj = req.get_subject()
|
||||
for (key,value) in name.items():
|
||||
setattr(subj, key, value)
|
||||
if subjectAltName:
|
||||
exts = []
|
||||
for altName in subjectAltName:
|
||||
exts.append(crypto.X509Extension("subjectAltName", True, "DNS:%s" % altName))
|
||||
req.add_extensions(exts)
|
||||
req.set_pubkey(pkey)
|
||||
req.sign(pkey, digest)
|
||||
return req
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue