-
Notifications
You must be signed in to change notification settings - Fork 3
/
certhash
executable file
·98 lines (70 loc) · 2.89 KB
/
certhash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env python3
#
# Copyright (c) 2020 Gareth Palmer <[email protected]>
# This program is free software, distributed under the terms of
# the GNU General Public License Version 2.
import sys
import os
import os.path
import base64
import getopt
import traceback
from cryptography import x509
from cryptography.hazmat import backends
from cryptography.hazmat.primitives import hashes, serialization
class ProgramError(Exception):
pass
def hash_certificate(certificate_file, hash_algorithm):
try:
with open(certificate_file, 'rb') as file:
certificate = file.read()
except (PermissionError, FileNotFoundError, IsADirectoryError) as error:
raise ProgramError(f'{error.strerror}: {error.filename}')
try:
certificate = x509.load_pem_x509_certificate(certificate, backends.default_backend())
except ValueError:
raise ProgramError(f'No certificate in file: {certificate_file}')
hash = hashes.Hash(hashes.SHA512() if hash_algorithm == 'sha512' else hashes.SHA1(), backends.default_backend())
hash.update(certificate.public_bytes(serialization.Encoding.DER))
certificate_hash = hash.finalize()
print(base64.b64encode(certificate_hash).decode('utf-8'))
def main():
try:
short_options = 'd:H'
long_options = ['digest=', 'help']
hash_algorithm = 'sha1'
certificate_file = None
help = False
try:
options, arguments = getopt.gnu_getopt(sys.argv[1:], short_options, long_options)
except getopt.GetoptError as error:
raise ProgramError(error.msg[0].upper() + error.msg[1:] +
'. Try \'' + os.path.basename(sys.argv[0]) + ' --help\' for more information')
for option, argument in options:
if option in ('-d', '--digest'):
hash_algorithm = argument
if hash_algorithm not in ('sha1', 'sha512'):
raise ProgramError(f'Invalid digest: {hash_algorithm}')
elif option in ('-H', '--help'):
help = True
if help:
print('Usage: ' + os.path.basename(sys.argv[0]) + ' [OPTIONS] CERT-FILE\n'
'Hash an x509 certificate and output as base64.\n'
'\n'
' -d, --digest ALGORITHM digest algorithm: sha1 or sha512 (default sha1)\n'
' -H, --help print this help and exit\n')
return
if len(arguments):
certificate_file = arguments[0]
if certificate_file is None:
raise ProgramError('No certificate file specified')
hash_certificate(certificate_file, hash_algorithm)
except ProgramError as error:
print(str(error), file = sys.stderr)
exit(1)
except Exception:
traceback.print_exc(file = sys.stderr)
exit(1)
exit(0)
if __name__ == '__main__':
main()