|
@@ -0,0 +1,203 @@
|
|
|
+
|
|
|
+from cryptography.hazmat.backends import default_backend
|
|
|
+from cryptography.hazmat.primitives import serialization
|
|
|
+from cryptography.hazmat.primitives.asymmetric import rsa
|
|
|
+
|
|
|
+from cryptography import x509
|
|
|
+from cryptography.x509.oid import NameOID
|
|
|
+from cryptography.hazmat.primitives import hashes
|
|
|
+
|
|
|
+import datetime
|
|
|
+
|
|
|
+c=u"GB"
|
|
|
+st=u"England"
|
|
|
+l=u"Manchester"
|
|
|
+o=u'Jisc'
|
|
|
+ou=u''
|
|
|
+servername = u"jadzia.mcc.ac.uk"
|
|
|
+crldp=u'http://somewhere.example.com/awebserver'
|
|
|
+passphrase=b'somethingsecure'
|
|
|
+
|
|
|
+
|
|
|
+def gen_cakey():
|
|
|
+ key = rsa.generate_private_key(
|
|
|
+ public_exponent=65537,
|
|
|
+ key_size=2048,
|
|
|
+ backend=default_backend()
|
|
|
+ )
|
|
|
+ return key
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def write_key_encrypted(filename,key,passphrase):
|
|
|
+ with open(filename, "wb") as f:
|
|
|
+ f.write(key.private_bytes(
|
|
|
+ encoding=serialization.Encoding.PEM,
|
|
|
+ format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
|
+ encryption_algorithm=serialization.BestAvailableEncryption(passphrase),
|
|
|
+ ))
|
|
|
+
|
|
|
+def output_key_encrypted(key,passphrase):
|
|
|
+ return key.private_bytes(
|
|
|
+ encoding=serialization.Encoding.PEM,
|
|
|
+ format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
|
+ encryption_algorithm=serialization.BestAvailableEncryption(passphrase),
|
|
|
+ )
|
|
|
+
|
|
|
+def write_key(filename,key):
|
|
|
+ with open(filename, "wb") as f:
|
|
|
+ f.write(key.private_bytes(
|
|
|
+ encoding=serialization.Encoding.PEM,
|
|
|
+ format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
|
+ encryption_algorithm=serialization.NoEncryption(),
|
|
|
+ ))
|
|
|
+
|
|
|
+def output_key(key):
|
|
|
+ return key.private_bytes(
|
|
|
+ encoding=serialization.Encoding.PEM,
|
|
|
+ format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
|
+ encryption_algorithm=serialization.NoEncryption(),
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def build_name(c,st,l,o,ou,cn):
|
|
|
+ array = []
|
|
|
+ if (c):
|
|
|
+ array.append(x509.NameAttribute(NameOID.COUNTRY_NAME,c))
|
|
|
+ if (st):
|
|
|
+ array.append(x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME,st))
|
|
|
+ if (l):
|
|
|
+ array.append(x509.NameAttribute(NameOID.LOCALITY_NAME,l))
|
|
|
+ if (o):
|
|
|
+ array.append(x509.NameAttribute(NameOID.ORGANIZATION_NAME,o))
|
|
|
+ if (ou):
|
|
|
+ array.append(x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME,ou))
|
|
|
+ if (cn):
|
|
|
+ array.append(x509.NameAttribute(NameOID.COMMON_NAME,cn))
|
|
|
+
|
|
|
+ return x509.Name(array)
|
|
|
+
|
|
|
+
|
|
|
+def build_rootca(key,subject,issuer,duration):
|
|
|
+
|
|
|
+ cert = x509.CertificateBuilder().subject_name(
|
|
|
+ subject
|
|
|
+ ).issuer_name(
|
|
|
+ issuer
|
|
|
+ ).public_key(
|
|
|
+ key.public_key()
|
|
|
+ ).serial_number(
|
|
|
+ x509.random_serial_number()
|
|
|
+ ).not_valid_before(
|
|
|
+ datetime.datetime.utcnow()
|
|
|
+ ).not_valid_after(
|
|
|
+ datetime.datetime.utcnow() + datetime.timedelta(days=duration)
|
|
|
+ ).add_extension(
|
|
|
+
|
|
|
+ x509.AuthorityKeyIdentifier.from_issuer_public_key(key.public_key()),
|
|
|
+ critical=False,
|
|
|
+ ).add_extension(
|
|
|
+ x509.SubjectKeyIdentifier.from_public_key(key.public_key()),
|
|
|
+ critical=False,
|
|
|
+ ).add_extension(
|
|
|
+ x509.BasicConstraints(True,None),
|
|
|
+ critical=True,
|
|
|
+ ).sign(key, hashes.SHA256(), default_backend())
|
|
|
+
|
|
|
+ return cert
|
|
|
+
|
|
|
+def build_servercert(key,root,csr,name,crldp,duration):
|
|
|
+
|
|
|
+ builder = x509.CertificateBuilder().subject_name(
|
|
|
+ csr.subject
|
|
|
+ ).issuer_name(
|
|
|
+ root.issuer
|
|
|
+ ).public_key(
|
|
|
+ csr.public_key()
|
|
|
+ ).serial_number(
|
|
|
+ x509.random_serial_number()
|
|
|
+ ).not_valid_before(
|
|
|
+ datetime.datetime.utcnow()
|
|
|
+ ).not_valid_after(
|
|
|
+ datetime.datetime.utcnow() + datetime.timedelta(days=duration)
|
|
|
+ ).add_extension(
|
|
|
+ x509.KeyUsage(True,True,True,False,False,False,False,False,False),
|
|
|
+ critical=True,
|
|
|
+ ).add_extension(
|
|
|
+ x509.SubjectAlternativeName([x509.DNSName(name)]),
|
|
|
+ critical=False,
|
|
|
+ ).add_extension(
|
|
|
+ x509.BasicConstraints(False,None),
|
|
|
+ critical=True,
|
|
|
+ ).add_extension(
|
|
|
+ x509.ExtendedKeyUsage([x509.ExtendedKeyUsageOID.SERVER_AUTH]),
|
|
|
+ critical=False,
|
|
|
+ ).add_extension(
|
|
|
+ x509.AuthorityKeyIdentifier.from_issuer_public_key(root.public_key()),
|
|
|
+ critical=False,
|
|
|
+ ).add_extension(
|
|
|
+ x509.SubjectKeyIdentifier.from_public_key(key.public_key()),
|
|
|
+ critical=False,
|
|
|
+ )
|
|
|
+
|
|
|
+ if ( crldp ):
|
|
|
+ builder = builder.add_extension(
|
|
|
+ x509.CRLDistributionPoints(
|
|
|
+ [x509.DistributionPoint(
|
|
|
+ [x509.UniformResourceIdentifier(crldp)],
|
|
|
+ None,
|
|
|
+ None,
|
|
|
+ None
|
|
|
+ )
|
|
|
+ ]
|
|
|
+ ),
|
|
|
+ critical=False,
|
|
|
+ )
|
|
|
+
|
|
|
+ cert = builder.sign(key, hashes.SHA256(), default_backend())
|
|
|
+
|
|
|
+ return cert
|
|
|
+
|
|
|
+def build_csr(key,subject,name):
|
|
|
+ csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name(
|
|
|
+ subject
|
|
|
+ )).add_extension(
|
|
|
+ x509.SubjectAlternativeName([
|
|
|
+ x509.DNSName(name),
|
|
|
+ ]),
|
|
|
+ critical=False,
|
|
|
+
|
|
|
+ ).sign(key, hashes.SHA256(), default_backend())
|
|
|
+
|
|
|
+ return csr
|
|
|
+
|
|
|
+def build_crl(key,issuer,duration):
|
|
|
+ builder = x509.CertificateRevocationListBuilder()
|
|
|
+ builder = builder.issuer_name(issuer)
|
|
|
+
|
|
|
+ builder = builder.last_update(datetime.datetime.today())
|
|
|
+ builder = builder.next_update(datetime.datetime.today() + datetime.timedelta(days=duration))
|
|
|
+
|
|
|
+ revoked_cert = x509.RevokedCertificateBuilder().serial_number(
|
|
|
+ x509.random_serial_number()
|
|
|
+ ).revocation_date(
|
|
|
+ datetime.datetime.today()
|
|
|
+ ).build(default_backend())
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ crl = builder.sign(
|
|
|
+ private_key=key, algorithm=hashes.SHA256(),
|
|
|
+ backend=default_backend()
|
|
|
+ )
|
|
|
+
|
|
|
+ return crl
|
|
|
+
|
|
|
+def write_cert(filename,cert):
|
|
|
+ with open(filename, "wb") as f:
|
|
|
+ f.write(cert.public_bytes(serialization.Encoding.PEM))
|
|
|
+
|
|
|
+def output_cert(cert):
|
|
|
+ return cert.public_bytes(serialization.Encoding.PEM)
|
|
|
+
|