]> Softwares of Agnibho - medscript.git/blob - signature.py
Reimplmented prescription signing with cryptography module
[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 from config import config
9 from datetime import datetime
10 from cryptography.hazmat.primitives.serialization import load_pem_private_key, Encoding
11 from cryptography.hazmat.primitives.asymmetric import padding
12 from cryptography.hazmat.primitives import hashes
13 from cryptography.hazmat.backends import default_backend
14 from cryptography.x509 import load_pem_x509_certificate
15
16 class Signature():
17
18 def sign(data, certificate, privkey, password=""):
19 with open(privkey, "rb") as f:
20 try:
21 priv=load_pem_private_key(f.read(), None, default_backend())
22 except TypeError:
23 priv=load_pem_private_key(f.read(), password.encode(), default_backend())
24 with open(certificate, "rb") as f:
25 cert=load_pem_x509_certificate(f.read())
26 signature=priv.sign(data.encode(), padding.PKCS1v15(), hashes.SHA256())
27 return signature
28
29 def verify(data, certificate, signature):
30 try:
31 if(not Signature.verify_chain(certificate)):
32 return False
33 except Exception as e:
34 print(e)
35 return False
36
37 with open(certificate, "rb") as f:
38 cert=load_pem_x509_certificate(f.read())
39 pub=cert.public_key()
40 try:
41 pub.verify(signature, data.encode(), padding.PKCS1v15(), hashes.SHA256())
42 subattr=""
43 for i in cert.subject:
44 subattr+=i.oid._name+":"+i.value+"\n"
45 return subattr
46 except Exception as e:
47 print(e)
48 return False
49
50 def verify_chain(cert_chain_path):
51 cert_chain=[]
52 with open(cert_chain_path) as chain_file:
53 cert_data=""
54 for line in chain_file:
55 cert_data=cert_data+line.strip()+"\n"
56 if "----END CERTIFICATE----" in line:
57 cert_chain.append(load_pem_x509_certificate(cert_data.encode()))
58 cert_data=""
59
60 for i in range(len(cert_chain)):
61 cert=cert_chain[i]
62 if(datetime.utcnow().timestamp()>cert.not_valid_after.timestamp()):
63 print("Certificate expired")
64 return False
65 if(i>0):
66 prev_cert=cert_chain[i-1]
67 try:
68 cert.public_key().verify(prev_cert.signature, prev_cert.tbs_certificate_bytes, padding.PKCS1v15(), prev_cert.signature_hash_algorithm)
69 except InvalidSignature:
70 print("Certificate chain signature verification failed")
71 return False
72 try:
73 with open(config["root_bundle"]) as root:
74 root_bundle=root.read()
75 if(cert_chain[-1].public_bytes(encoding=Encoding.PEM).decode() not in root_bundle):
76 print("Certificate not in root bundle")
77 return False
78 return True
79 except Exception as e:
80 print(e)
81 print("Root bundle could not be loaded")
82 return False