]> Softwares of Agnibho - medscript.git/blob - signature.py
Bugfix: Windows uninstall package permission error
[medscript.git] / signature.py
1 # MedScript
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/>.
7
8 import logging
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
16
17 class Signature():
18
19 def sign(data, certificate, privkey, password=""):
20 with open(privkey, "rb") as f:
21 try:
22 priv=load_pem_private_key(f.read(), None, default_backend())
23 except TypeError:
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())
28 return signature
29
30 def verify(data, certificate, signature):
31 try:
32 if(not Signature.verify_chain(certificate)):
33 return False
34 except Exception as e:
35 logging.exception(e)
36 return False
37
38 with open(certificate, "rb") as f:
39 cert=load_pem_x509_certificate(f.read())
40 pub=cert.public_key()
41 try:
42 pub.verify(signature, data.encode(), padding.PKCS1v15(), hashes.SHA256())
43 subattr=""
44 for i in cert.subject:
45 subattr+=i.oid._name+":"+i.value+"\n"
46 return subattr
47 except Exception as e:
48 logging.exception(e)
49 return False
50
51 def verify_chain(cert_chain_path):
52 cert_chain=[]
53 with open(cert_chain_path) as chain_file:
54 cert_data=""
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()))
59 cert_data=""
60
61 for i in range(len(cert_chain)):
62 cert=cert_chain[i]
63 if(datetime.utcnow().timestamp()>cert.not_valid_after.timestamp()):
64 logging.warning("Certificate expired")
65 return False
66 if(i>0):
67 prev_cert=cert_chain[i-1]
68 try:
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")
72 return False
73 try:
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")
78 return False
79 return True
80 except Exception as e:
81 logging.warning(e)
82 logging.warning("Root bundle could not be loaded")
83 return False