-
Notifications
You must be signed in to change notification settings - Fork 1
/
eidas_tl.py
66 lines (59 loc) · 2.96 KB
/
eidas_tl.py
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
import argparse
import os
import requests
from lxml import etree
def main():
# Define CLI arguments
parser = argparse.ArgumentParser(
description='Extracting CA certificates from the EU Trusted List for a given country and service type.'
)
parser.add_argument('service', choices=['QWAC', 'QSealC'], help=(
'Type of service to retrieve certificate for. '
'QWAC - Qualified certificate for website authentication; '
'QSealC - Qualified certificate for electronic seal'))
parser.add_argument('country', help='ISO 3166-1 alpha-2 country code (only EEA countries are supported)')
parser.add_argument('--target_folder', help='Target folder to save certificate files in')
args = parser.parse_args()
# Define service URI based on argument
if args.service == 'QWAC':
service_uri = 'http://uri.etsi.org/TrstSvc/TrustedList/SvcInfoExt/ForWebSiteAuthentication'
elif args.service == 'QSealC':
service_uri = 'http://uri.etsi.org/TrstSvc/TrustedList/SvcInfoExt/ForeSeals'
# Download XML file
url = f'https://eidas.ec.europa.eu/efda/tl-browser/api/v1/browser/download/{args.country}'
response = requests.get(url)
xml_content = response.content
# Parse XML and evaluate XPath expression
root = etree.fromstring(xml_content)
namespaces = root.nsmap
if namespaces.get(None, None):
namespaces['tsl'] = namespaces.pop(None)
xpath_expr = (
"//tsl:TSPService["
"tsl:ServiceInformation/tsl:ServiceTypeIdentifier='http://uri.etsi.org/TrstSvc/Svctype/CA/QC' and "
"tsl:ServiceInformation/tsl:ServiceStatus='http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted' and "
"tsl:ServiceInformation/tsl:ServiceInformationExtensions/tsl:Extension["
f"tsl:AdditionalServiceInformation/tsl:URI[text()='{service_uri}']]]"
)
elements = root.xpath(xpath_expr, namespaces=namespaces)
# Extract X.509 certificate from found elements and write to file
if elements:
target_folder = args.target_folder
os.makedirs(target_folder, exist_ok=True)
for i, element in enumerate(elements):
name_elem = element.find(".//tsl:ServiceName/tsl:Name", namespaces)
print(f'Extracting: {name_elem.text}')
cert_elem = element.find('.//tsl:X509Certificate', namespaces)
if cert_elem is not None:
cert_str = cert_elem.text.strip().replace(' ', '').replace('\n', '')
wrapped_cert_str = "-----BEGIN CERTIFICATE-----\n"
for j in range(0, len(cert_str), 64):
wrapped_cert_str += cert_str[j:j+64] + "\n"
wrapped_cert_str += "-----END CERTIFICATE-----\n"
filename = f'{args.country}_{i}.pem'
filepath = os.path.join(target_folder, filename)
with open(filepath, 'w') as f:
f.write(wrapped_cert_str)
print(f'Wrote {filepath}')
if __name__ == '__main__':
main()