2 # Copyright (C) 2023 Dr. Agnibho Mondal
3 # This file is part of MedScript.
4 # MedScript is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
5 # MedScript is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6 # You should have received a copy of the GNU General Public License along with MedScript. If not, see <https://www.gnu.org/licenses/>.
9 from config
import config
10 from datetime
import datetime
11 from cryptography
.hazmat
.primitives
.serialization
import load_pem_private_key
, Encoding
12 from cryptography
.hazmat
.primitives
.asymmetric
import padding
13 from cryptography
.hazmat
.primitives
import hashes
14 from cryptography
.hazmat
.backends
import default_backend
15 from cryptography
.x509
import load_pem_x509_certificate
19 def sign(data
, certificate
, privkey
, password
=""):
20 with
open(privkey
, "rb") as f
:
22 priv
=load_pem_private_key(f
.read(), None, default_backend())
24 priv
=load_pem_private_key(f
.read(), password
.encode(), default_backend())
25 with
open(certificate
, "rb") as f
:
26 cert
=load_pem_x509_certificate(f
.read())
27 signature
=priv
.sign(data
.encode(), padding
.PKCS1v15(), hashes
.SHA256())
30 def verify(data
, certificate
, signature
):
32 if(not Signature
.verify_chain(certificate
)):
34 except Exception as e
:
38 with
open(certificate
, "rb") as f
:
39 cert
=load_pem_x509_certificate(f
.read())
42 pub
.verify(signature
, data
.encode(), padding
.PKCS1v15(), hashes
.SHA256())
44 for i
in cert
.subject
:
45 subattr
+=i
.oid
._name
+":"+i
.value
+"\n"
47 except Exception as e
:
51 def verify_chain(cert_chain_path
):
53 with
open(cert_chain_path
) as chain_file
:
55 for line
in chain_file
:
56 cert_data
=cert_data
+line
.strip()+"\n"
57 if "----END CERTIFICATE----" in line
:
58 cert_chain
.append(load_pem_x509_certificate(cert_data
.encode()))
61 for i
in range(len(cert_chain
)):
63 if(datetime
.utcnow().timestamp()>cert
.not_valid_after
.timestamp()):
64 logging
.warning("Certificate expired")
67 prev_cert
=cert_chain
[i
-1]
69 cert
.public_key().verify(prev_cert
.signature
, prev_cert
.tbs_certificate_bytes
, padding
.PKCS1v15(), prev_cert
.signature_hash_algorithm
)
70 except InvalidSignature
:
71 logging
.warning("Certificate chain signature verification failed")
74 with
open(config
["root_bundle"]) as root
:
75 root_bundle
=root
.read()
76 if(cert_chain
[-1].public_bytes(encoding
=Encoding
.PEM
).decode() not in root_bundle
):
77 logging
.warning("Certificate not in root bundle")
80 except Exception as e
:
82 logging
.warning("Root bundle could not be loaded")