11#!/usr/bin/env python3
2- #encoding=utf-8
32import os
43import sys
54import random
5+ import datetime
6+
67from hashlib import sha256
7- from OpenSSL import crypto
8+ from cryptography .hazmat .primitives .asymmetric import rsa
9+ from cryptography .hazmat .primitives import hashes , serialization
10+ from cryptography .hazmat .backends import default_backend
11+ from cryptography .x509 import (
12+ Name ,
13+ NameAttribute ,
14+ CertificateBuilder ,
15+ CertificateSigningRequestBuilder ,
16+ DNSName ,
17+ SubjectAlternativeName ,
18+ load_pem_x509_certificate ,
19+ BasicConstraints ,
20+ KeyUsage ,
21+ )
22+ from cryptography .x509 .oid import NameOID
823
924CN = "lamda"
1025if len (sys .argv ) == 2 :
1126 CN = sys .argv [1 ]
1227
1328if os .path .isfile ("root.key" ):
14- data = open ("root.key" , "rb" ).read ()
15- rk = crypto .load_privatekey (crypto .FILETYPE_PEM , data )
29+ with open ("root.key" , "rb" ) as f :
30+ rk = serialization .load_pem_private_key (
31+ f .read (), password = None , backend = default_backend ()
32+ )
1633else :
17- rk = crypto .PKey ()
18- rk .generate_key (crypto .TYPE_RSA , 2048 )
19-
20- data = crypto .dump_privatekey (crypto .FILETYPE_PEM , rk )
21- open ("root.key" , "wb" ).write (data )
34+ rk = rsa .generate_private_key (
35+ public_exponent = 65537 , key_size = 2048 , backend = default_backend ()
36+ )
37+ with open ("root.key" , "wb" ) as f :
38+ f .write (
39+ rk .private_bytes (
40+ encoding = serialization .Encoding .PEM ,
41+ format = serialization .PrivateFormat .TraditionalOpenSSL ,
42+ encryption_algorithm = serialization .NoEncryption (),
43+ )
44+ )
2245
2346if os .path .isfile ("root.crt" ):
24- data = open ("root.crt" , "rb" ). read ()
25- root = crypto . load_certificate ( crypto . FILETYPE_PEM , data )
47+ with open ("root.crt" , "rb" ) as f :
48+ root = load_pem_x509_certificate ( f . read (), default_backend () )
2649else :
27- root = crypto .X509 ()
28-
29- root .get_subject ().O = "LAMDA"
30-
31- root .gmtime_adj_notBefore (0 )
32- root .gmtime_adj_notAfter (315360000 )
33- root .set_issuer (root .get_subject ())
34- root .set_pubkey (rk )
35- root .sign (rk , "sha256" )
36-
37- data = crypto .dump_certificate (crypto .FILETYPE_PEM , root )
38- open ("root.crt" , "wb" ).write (data )
39-
40- if not os .path .isfile ("{}.pem" .format (CN )):
41- pk = crypto .PKey ()
42- pk .generate_key (crypto .TYPE_RSA , 2048 )
50+ subject = issuer = Name (
51+ [
52+ NameAttribute (NameOID .ORGANIZATION_NAME , "LAMDA" ),
53+ NameAttribute (NameOID .COMMON_NAME , "FireRPA LAMDA Root Trust" ),
54+ ]
55+ )
56+ root = (
57+ CertificateBuilder ()
58+ .subject_name (subject )
59+ .issuer_name (issuer )
60+ .not_valid_before (datetime .datetime .utcnow ())
61+ .not_valid_after (datetime .datetime .utcnow () + datetime .timedelta (days = 3650 ))
62+ .public_key (rk .public_key ())
63+ .serial_number (random .randint (1 , 2 ** 128 ))
64+ .add_extension (BasicConstraints (ca = True , path_length = None ), critical = True )
65+ .sign (rk , hashes .SHA256 (), default_backend ())
66+ )
67+ with open ("root.crt" , "wb" ) as f :
68+ f .write (root .public_bytes (serialization .Encoding .PEM ))
4369
44- req = crypto .X509Req ()
45- req .set_version (0 )
46- req .get_subject ().CN = CN
47- req .set_pubkey (pk )
48- req .sign (pk , "sha256" )
4970
50- cert = crypto . X509 ()
51- cert . set_version ( 2 )
52- cert . set_subject ( req . get_subject () )
53- cert . set_serial_number ( random . randint ( 1 , 2 ** 128 ) )
54- cert . gmtime_adj_notBefore ( 0 )
55- cert . gmtime_adj_notAfter ( 315360000 )
56- cert . set_issuer ( root . get_subject ( ))
57- cert . set_pubkey ( req . get_pubkey ())
58- cert . sign ( rk , "sha256" )
71+ if not os . path . isfile ( f" { CN } .pem" ):
72+ pk = rsa . generate_private_key (
73+ public_exponent = 65537 , key_size = 2048 , backend = default_backend ( )
74+ )
75+ csr = (
76+ CertificateSigningRequestBuilder ( )
77+ . subject_name ( Name ([ NameAttribute ( NameOID . COMMON_NAME , CN )] ))
78+ . sign ( pk , hashes . SHA256 (), default_backend ())
79+ )
5980
60- pkey = crypto .dump_privatekey (crypto .FILETYPE_PEM , pk )
61- cert = crypto .dump_certificate (crypto .FILETYPE_PEM , cert )
62- root = crypto .dump_certificate (crypto .FILETYPE_PEM , root )
81+ cert = (
82+ CertificateBuilder ()
83+ .subject_name (csr .subject )
84+ .issuer_name (root .subject )
85+ .not_valid_before (datetime .datetime .utcnow ())
86+ .not_valid_after (datetime .datetime .utcnow () + datetime .timedelta (days = 3650 ))
87+ .public_key (csr .public_key ())
88+ .serial_number (random .randint (1 , 2 ** 128 ))
89+ .sign (rk , hashes .SHA256 (), default_backend ())
90+ )
6391
64- d = pk .to_cryptography_key ().private_numbers ().d
65- pd = d .to_bytes ((d .bit_length () + 7 ) // 8 , "little" )
66- cred = sha256 (pd ).hexdigest ()[::3 ]
92+ with open (f"{ CN } .pem" , "wb" ) as output :
93+ pem_private_key = pk .private_bytes (
94+ encoding = serialization .Encoding .PEM ,
95+ format = serialization .PrivateFormat .TraditionalOpenSSL ,
96+ encryption_algorithm = serialization .NoEncryption (),
97+ )
98+ pem_cert = cert .public_bytes (serialization .Encoding .PEM )
99+ pem_root = root .public_bytes (serialization .Encoding .PEM )
67100
68- f = open ( "{}.pem" . format ( CN ), "wb" )
69- hdr = "LAMDA SSL CERTIFICATE (CN={},PASSWD={})" . format ( CN , cred )
70- os . chmod ( f . name , 0o600 )
101+ d = pk . private_numbers (). d
102+ pd = d . to_bytes (( d . bit_length () + 7 ) // 8 , "little" )
103+ cred = sha256 ( pd ). hexdigest ()[:: 3 ]
71104
72- f .write (hdr .encode ())
73- f .write (b"\n " )
74- f .write (pkey .strip ())
75- f .write (b"\n " )
76- f .write (cert .strip ())
77- f .write (b"\n " )
78- f .write (root .strip ())
79- f .write (b"\n " )
80- f .close ()
105+ header = f"LAMDA SSL CERTIFICATE (CN={ CN } ,PASSWD={ cred } )\n "
106+ output .write (header .encode ())
107+ output .write (pem_private_key .strip ())
108+ output .write (b"\n " )
109+ output .write (pem_cert .strip ())
110+ output .write (b"\n " )
111+ output .write (pem_root .strip ())
112+ output .write (b"\n " )
0 commit comments