Skip to content

Commit d4ed42d

Browse files
DarsstarDos Moonen
and
Dos Moonen
authored
Platform specific TLS/SSL configuration context (#53)
* Add PKCS #12 ca file for Windows * Refactor SslConfigurationContext into platform specific classes * Rip the CRL extension from the certificates for Windows * Update tls_example.py --------- Co-authored-by: Dos Moonen <[email protected]>
1 parent 4d290d5 commit d4ed42d

15 files changed

+300
-98
lines changed

.ci/certs/ca.p12

2.67 KB
Binary file not shown.

.ci/certs/client.p12

155 Bytes
Binary file not shown.

.ci/certs/client_certificate.pem

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-----BEGIN CERTIFICATE-----
2-
MIID7zCCAtegAwIBAgIBAjANBgkqhkiG9w0BAQsFADBMMTswOQYDVQQDDDJUTFNH
2+
MIIDvDCCAqSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBMMTswOQYDVQQDDDJUTFNH
33
ZW5TZWxmU2lnbmVkdFJvb3RDQSAyMDIzLTA5LTExVDIwOjUxOjM5LjYwMzAxMzEN
44
MAsGA1UEBwwEJCQkJDAeFw0yMzA5MTExODUxNDBaFw0zMzA5MDgxODUxNDBaMDYx
55
IzAhBgNVBAMMGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tMQ8wDQYDVQQKDAZj
@@ -9,16 +9,14 @@ p8kuK93PxM0qsYxvCj5fywaGI2mL9sNibrs6CFtvPL+Rj57LSt5UJHSaH3LmY0CE
99
bV2OdBEuYEBR7eGtzmpupmA+PptHF/U0hTmfIaet6sVLjvJTmD2/3LcztNm/8ksH
1010
iqeHgJDUE+ERWUVl7AEcBo1rHDJw+z/jsKEtKbmqoNxsfcdb2UdZw9cJkB5ojKMr
1111
l73m35s9uIWZxf2iNd3/tqos7cXMLJcTpwr4x6n6F+PsMhBK5sVTw+kFkq+iyxsu
12-
nSVpVT6nAgMBAAGjgfEwge4wCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwEwYDVR0l
13-
BAwwCgYIKwYBBQUHAwIwTAYDVR0RBEUwQ4IaZ3NhbnRvbWFnZzZMVkRNLnZtd2Fy
14-
ZS5jb22CGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tgglsb2NhbGhvc3QwMQYD
15-
VR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC1zZXJ2ZXI6ODAwMC9iYXNpYy5jcmww
16-
HQYDVR0OBBYEFF+biSCzxAazbay1NaTfGDWawU6dMB8GA1UdIwQYMBaAFCjyUnXF
17-
pZI5+zz7PJxHxDuulqqZMA0GCSqGSIb3DQEBCwUAA4IBAQCREnq62BDzp61MRlzL
18-
lsheI/13hkLutFl+OJAoNGcSgprys7d0zwQJGakCO5o05Csi1pQmP0MCKSyPN2Xb
19-
CTEb1qeDBt3FQkgSzXUCAjVL2wvWoL1nIZaAkD5XDjDvGr5Yd4Eczc7WYwujlT5B
20-
JausVa/ShyYatuiTfgPI7UKASW625fkdi+h30OxQ6vnP+X3FUjOV5NO5/GSrlyFN
21-
Fk0M1YqcypUa9meFooDo2aSMTF8zUuZKsOhFLO9B1z7Io/iAiACdPvjdZWjcpJmI
22-
m+gUWeyMH/R4ql6VlPaitUus+CUWkWtdNuQIZEH8HKR1CIOeCW3xwmIJCK9rnbvI
23-
oGb4
12+
nSVpVT6nAgMBAAGjgb4wgbswTAYDVR0RBEUwQ4IaZ3NhbnRvbWFnZzZMVkRNLnZt
13+
d2FyZS5jb22CGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tgglsb2NhbGhvc3Qw
14+
CQYDVR0TBAIwADAfBgNVHSMEGDAWgBQo8lJ1xaWSOfs8+zycR8Q7rpaqmTAdBgNV
15+
HQ4EFgQUX5uJILPEBrNtrLU1pN8YNZrBTp0wCwYDVR0PBAQDAgWgMBMGA1UdJQQM
16+
MAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAbfphg4JZuCmxoAzXhbDdB
17+
48K98aPVv4ABa6L8BrJcWcXo9H/q0puC2+4LtLNAX7M/hri+UcIWDt2nG+9qkUYN
18+
HXZCfpgZo99FbpfmPlk/m7mBqB6YBFYx94VzcHGTipsOVEfSmOMybf+XW8KPJrXd
19+
ZhsbrAu1ev3k85P8jkv7psc+TKG+HjCG3Rqiy73gMpNvWRQriEO2yOa0sx5Pct+l
20+
x0KBlXNLQc37gddV08BgcTn6fsS72FbjMh0GXbG1mZMCA4DxpRlhwkWqaHCbcfFq
21+
3LKBCvuz/ysAEeJoWug8LKHly8p1Gpelot+tj/lFEYryOr6whJI5xoN6VxNHp67S
2422
-----END CERTIFICATE-----

.ci/certs/server.p12

187 Bytes
Binary file not shown.

.ci/certs/server_certificate.pem

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
-----BEGIN CERTIFICATE-----
2-
MIID7zCCAtegAwIBAgIBATANBgkqhkiG9w0BAQsFADBMMTswOQYDVQQDDDJUTFNH
3-
ZW5TZWxmU2lnbmVkdFJvb3RDQSAyMDIzLTA5LTExVDIwOjUxOjM5LjYwMzAxMzEN
4-
MAsGA1UEBwwEJCQkJDAeFw0yMzA5MTExODUxNDBaFw0zMzA5MDgxODUxNDBaMDYx
5-
IzAhBgNVBAMMGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tMQ8wDQYDVQQKDAZz
6-
ZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6H9gnMoGCmgDN
7-
GXpqgLiIJBmDvbo64P+FsPOvKEYFNKj/Poz2UVVY96kOJRDTBXW3p42C0GCll/2z
8-
/4RcOwN4Jcf4TIU+IsytOyQ39FYNVMDJpMzH4dQPYlvx9euyIqxUccTYCiXtHkrd
9-
xw5cV3gs7HPQLcklQtBgoVNnlf1fPQcPgYPa5x95+oEki2yWhScXa9EP3W6G+KXE
10-
guCi1enoIZ3+MfxbEkfdm+C9Yo47vh6LXcokyKpiuOYk2TGrfaw5JQb1tRwb4BOQ
11-
ORriMCHi6+TkQf58yQ5GRZvJ5sjBeJgLtmCvRJXbdZXcw25jKXPwz74qS1Q728kD
12-
c2k7lgKvAgMBAAGjgfEwge4wCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwEwYDVR0l
13-
BAwwCgYIKwYBBQUHAwEwTAYDVR0RBEUwQ4IaZ3NhbnRvbWFnZzZMVkRNLnZtd2Fy
14-
ZS5jb22CGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tgglsb2NhbGhvc3QwHQYD
15-
VR0OBBYEFG5VGCQucC7FqyOJOTzIYtclS9/SMB8GA1UdIwQYMBaAFCjyUnXFpZI5
16-
+zz7PJxHxDuulqqZMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwtc2VydmVy
17-
OjgwMDAvYmFzaWMuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQB3nWIIa+9Oo29gU0us
18-
fvryYJo92A/mEGIBpixX2i4eQoPhgTSJvFWN3QCHDexbnccM6tRksQmKwn5Rrf+P
19-
DdM8BiTLP/jOQWJXChZro8xpHLmNjlOGletsQ7wo7/p5hvD6Y7pB6FK6LdLcbwbI
20-
Rmvy8olsfOMewEyyWLbKB7e7+iwDIO5lxxgNWXKspO+Kx7wgVeS3j2OhLaOBj1N4
21-
a+YAXVVaN3IkkdHwUHBTPfuvguXCD8fZxVW5RkYDiweeHAMuwpu3o2rd7y2dGzG7
22-
u5mLzNazq4Ki/FTSZMkMAloN4/vfXQfGUO4UJcGXB/c3XO9XURsF2N1k0T9ThIUh
23-
bhmL
2+
MIIDzzCCAregAwIBAgIUeRECMRSdARujrzjF1SEBlULbo4IwDQYJKoZIhvcNAQEL
3+
BQAwTDE7MDkGA1UEAwwyVExTR2VuU2VsZlNpZ25lZHRSb290Q0EgMjAyMy0wOS0x
4+
MVQyMDo1MTozOS42MDMwMTMxDTALBgNVBAcMBCQkJCQwHhcNMjUwMjI2MTUyNDA1
5+
WhcNMjYwMjI2MTUyNDA1WjA2MSMwIQYDVQQDDBpnc2FudG9tYWdnNkxWRE0udm13
6+
YXJlLmNvbTEPMA0GA1UECgwGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
7+
MIIBCgKCAQEAuh/YJzKBgpoAzRl6aoC4iCQZg726OuD/hbDzryhGBTSo/z6M9lFV
8+
WPepDiUQ0wV1t6eNgtBgpZf9s/+EXDsDeCXH+EyFPiLMrTskN/RWDVTAyaTMx+HU
9+
D2Jb8fXrsiKsVHHE2Aol7R5K3ccOXFd4LOxz0C3JJULQYKFTZ5X9Xz0HD4GD2ucf
10+
efqBJItsloUnF2vRD91uhvilxILgotXp6CGd/jH8WxJH3ZvgvWKOO74ei13KJMiq
11+
YrjmJNkxq32sOSUG9bUcG+ATkDka4jAh4uvk5EH+fMkORkWbyebIwXiYC7Zgr0SV
12+
23WV3MNuYylz8M++KktUO9vJA3NpO5YCrwIDAQABo4G+MIG7MEwGA1UdEQRFMEOC
13+
GmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tghpnc2FudG9tYWdnNkxWRE0udm13
14+
YXJlLmNvbYIJbG9jYWxob3N0MAkGA1UdEwQCMAAwHwYDVR0jBBgwFoAUKPJSdcWl
15+
kjn7PPs8nEfEO66WqpkwHQYDVR0OBBYEFG5VGCQucC7FqyOJOTzIYtclS9/SMAsG
16+
A1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOC
17+
AQEAemxaoori7vi3+drMpOSSmeqG/lmtupuoX7ysbYlhZenRPGAOiGTEMaafwp7E
18+
bsBFG+vHajY9bLMesVCbKXPJS5KzvAHq4nIQeI7ravUAKUb4wGin6Hsqma6ac7vc
19+
0U8jVGKStr+Ax9Xvu1YbZLIPyrWXL9d8pDsVogGySXKYU9fBfiohcwvdZTnXnHaY
20+
FkpMcYORJywNulz53jHspIjKTf+jCG/LC4pWsyidmNsDUZlDePVB5wR/ycFUGzdi
21+
OjGRZUvQ2+UNmbLdmzfqIHursON8I/7t22ogeCbY/hX1S29zMpNjzZ4XagWDtLUf
22+
BDnD2qWuKVvdPm9YiRckNlWxNQ==
2423
-----END CERTIFICATE-----

examples/getting_started/getting_started.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# type: ignore
22

33

4-
from rabbitmq_amqp_python_client import ( # SSlConfigurationContext,; SslConfigurationContext,; ClientCert,
4+
from rabbitmq_amqp_python_client import ( # PosixSSlConfigurationContext,; PosixClientCert,
55
AddressHelper,
66
AMQPMessagingHandler,
77
Connection,
@@ -68,7 +68,7 @@ def create_connection(environment: Environment) -> Connection:
6868
# client_key = ".ci/certs/client_key.pem"
6969
# connection = Connection(
7070
# "amqps://guest:guest@localhost:5671/",
71-
# ssl_context=SslConfigurationContext(
71+
# ssl_context=PosixSslConfigurationContext(
7272
# ca_cert=ca_cert_file,
7373
# client_cert=ClientCert(client_cert=client_cert, client_key=client_key),
7474
# ),

examples/streams/example_with_streams.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# type: ignore
22

3-
from rabbitmq_amqp_python_client import ( # SSlConfigurationContext,; SslConfigurationContext,; ClientCert,
3+
from rabbitmq_amqp_python_client import ( # PosixSSlConfigurationContext,; PosixClientCert,
44
AddressHelper,
55
AMQPMessagingHandler,
66
Connection,
@@ -72,9 +72,9 @@ def create_connection(environment: Environment) -> Connection:
7272
# client_key = ".ci/certs/client_key.pem"
7373
# connection = Connection(
7474
# "amqps://guest:guest@localhost:5671/",
75-
# ssl_context=SslConfigurationContext(
75+
# ssl_context=PosixSslConfigurationContext(
7676
# ca_cert=ca_cert_file,
77-
# client_cert=ClientCert(client_cert=client_cert, client_key=client_key),
77+
# client_cert=PosixClientCert(client_cert=client_cert, client_key=client_key),
7878
# ),
7979
# )
8080
connection.dial()

examples/tls/tls_example.py

Lines changed: 78 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
# type: ignore
2+
import sys
3+
from traceback import print_exception
24

3-
4-
from rabbitmq_amqp_python_client import ( # SSlConfigurationContext,; SslConfigurationContext,; ClientCert,
5+
from rabbitmq_amqp_python_client import (
56
AddressHelper,
67
AMQPMessagingHandler,
7-
ClientCert,
88
Connection,
9+
CurrentUserStore,
910
Environment,
1011
Event,
1112
ExchangeSpecification,
1213
ExchangeToQueueBindingSpecification,
14+
LocalMachineStore,
1315
Message,
16+
PKCS12Store,
17+
PosixClientCert,
18+
PosixSslConfigurationContext,
1419
QuorumQueueSpecification,
15-
SslConfigurationContext,
20+
WinClientCert,
21+
WinSslConfigurationContext,
22+
)
23+
from rabbitmq_amqp_python_client.ssl_configuration import (
24+
FriendlyName,
1625
)
1726

1827
messages_to_publish = 100
@@ -74,20 +83,75 @@ def main() -> None:
7483
exchange_name = "test-exchange"
7584
queue_name = "example-queue"
7685
routing_key = "routing-key"
86+
ca_p12_store = ".ci/certs/ca.p12"
7787
ca_cert_file = ".ci/certs/ca_certificate.pem"
7888
client_cert = ".ci/certs/client_certificate.pem"
7989
client_key = ".ci/certs/client_key.pem"
90+
client_p12_store = ".ci/certs/client.p12"
91+
uri = "amqps://guest:guest@localhost:5671/"
92+
93+
if sys.platform == "win32":
94+
ca_stores = [
95+
# names for the current user and local machine are not
96+
# case-sensitive
97+
CurrentUserStore(name="Root"),
98+
LocalMachineStore(name="Root"),
99+
PKCS12Store(path=ca_p12_store),
100+
]
101+
client_stores = [
102+
# `personal` is treated as an alias for `my` by qpid proton
103+
# Recommended read:
104+
# https://github.com/apache/qpid-proton/blob/2847000fbb3732e80537e3c3ff5e097bb95bfae0/c/src/ssl/PLATFORM_NOTES.md
105+
CurrentUserStore(name="Personal"),
106+
LocalMachineStore(name="my"),
107+
PKCS12Store(path=client_p12_store),
108+
]
109+
110+
for ca_store, client_store in zip(ca_stores, client_stores):
111+
ssl_context = WinSslConfigurationContext(
112+
ca_store=ca_store,
113+
client_cert=WinClientCert(
114+
store=client_store,
115+
# qpid proton uses Windows constant CERT_NAME_FRIENDLY_DISPLAY_TYPE
116+
# to retrieve the value which is compare to the one we provide
117+
# If certificates have no friendly name Windows falls back to
118+
# CERT_NAME_SIMPLE_DISPLAY_TYPE which has further fallbacks
119+
# https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetnamestringa
120+
disambiguation_method=FriendlyName("1"),
121+
password=None,
122+
),
123+
)
124+
environment = Environment(
125+
uri,
126+
ssl_context=ssl_context,
127+
)
128+
129+
try:
130+
print("connection to amqp server")
131+
connection = create_connection(environment)
132+
break
133+
except Exception as e:
134+
print_exception(e)
135+
continue
136+
else:
137+
raise RuntimeError(
138+
"connection failed. working directory should be project root"
139+
)
140+
else:
141+
environment = Environment(
142+
uri,
143+
ssl_context=PosixSslConfigurationContext(
144+
ca_cert=ca_cert_file,
145+
client_cert=PosixClientCert(
146+
client_cert=client_cert,
147+
client_key=client_key,
148+
password=None,
149+
),
150+
),
151+
)
80152

81-
environment = Environment(
82-
"amqps://guest:guest@localhost:5671/",
83-
ssl_context=SslConfigurationContext(
84-
ca_cert=ca_cert_file,
85-
client_cert=ClientCert(client_cert=client_cert, client_key=client_key),
86-
),
87-
)
88-
89-
print("connection to amqp server")
90-
connection = create_connection(environment)
153+
print("connection to amqp server")
154+
connection = create_connection(environment)
91155

92156
management = connection.management()
93157

rabbitmq_amqp_python_client/__init__.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,13 @@
3232
StreamSpecification,
3333
)
3434
from .ssl_configuration import (
35-
ClientCert,
36-
SslConfigurationContext,
35+
CurrentUserStore,
36+
LocalMachineStore,
37+
PKCS12Store,
38+
PosixClientCert,
39+
PosixSslConfigurationContext,
40+
WinClientCert,
41+
WinSslConfigurationContext,
3742
)
3843

3944
try:
@@ -69,8 +74,13 @@
6974
"AMQPMessagingHandler",
7075
"ArgumentOutOfRangeException",
7176
"ValidationCodeException",
72-
"SslConfigurationContext",
73-
"ClientCert",
77+
"PosixSslConfigurationContext",
78+
"WinSslConfigurationContext",
79+
"PosixClientCert",
80+
"WinClientCert",
81+
"LocalMachineStore",
82+
"CurrentUserStore",
83+
"PKCS12Store",
7484
"ConnectionClosed",
7585
"StreamOptions",
7686
"OffsetSpecification",

rabbitmq_amqp_python_client/connection.py

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
import logging
2-
from typing import Annotated, Callable, Optional, TypeVar
2+
from typing import (
3+
Annotated,
4+
Callable,
5+
Optional,
6+
TypeVar,
7+
Union,
8+
)
9+
10+
import typing_extensions
311

412
from .address_helper import validate_address
513
from .consumer import Consumer
@@ -10,7 +18,15 @@
1018
from .qpid.proton._handlers import MessagingHandler
1119
from .qpid.proton._transport import SSLDomain
1220
from .qpid.proton.utils import BlockingConnection
13-
from .ssl_configuration import SslConfigurationContext
21+
from .ssl_configuration import (
22+
CurrentUserStore,
23+
FriendlyName,
24+
LocalMachineStore,
25+
PKCS12Store,
26+
PosixSslConfigurationContext,
27+
Unambiguous,
28+
WinSslConfigurationContext,
29+
)
1430

1531
logger = logging.getLogger(__name__)
1632

@@ -34,7 +50,9 @@ def __init__(
3450
uri: Optional[str] = None,
3551
# multi-node mode
3652
uris: Optional[list[str]] = None,
37-
ssl_context: Optional[SslConfigurationContext] = None,
53+
ssl_context: Union[
54+
PosixSslConfigurationContext, WinSslConfigurationContext, None
55+
] = None,
3856
on_disconnection_handler: Optional[CB] = None, # type: ignore
3957
):
4058
"""
@@ -60,7 +78,9 @@ def __init__(
6078
self._conn: BlockingConnection
6179
self._management: Management
6280
self._on_disconnection_handler = on_disconnection_handler
63-
self._conf_ssl_context: Optional[SslConfigurationContext] = ssl_context
81+
self._conf_ssl_context: Union[
82+
PosixSslConfigurationContext, WinSslConfigurationContext, None
83+
] = ssl_context
6484
self._ssl_domain = None
6585
self._connections = [] # type: ignore
6686
self._index: int = -1
@@ -80,17 +100,47 @@ def dial(self) -> None:
80100
logger.debug("Enabling SSL")
81101

82102
self._ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
83-
if self._ssl_domain is not None:
84-
self._ssl_domain.set_trusted_ca_db(self._conf_ssl_context.ca_cert)
103+
assert self._ssl_domain
104+
105+
if isinstance(self._conf_ssl_context, PosixSslConfigurationContext):
106+
ca_cert = self._conf_ssl_context.ca_cert
107+
elif isinstance(self._conf_ssl_context, WinSslConfigurationContext):
108+
ca_cert = self._win_store_to_cert(self._conf_ssl_context.ca_store)
109+
else:
110+
typing_extensions.assert_never(self._conf_ssl_context)
111+
self._ssl_domain.set_trusted_ca_db(ca_cert)
112+
85113
# for mutual authentication
86114
if self._conf_ssl_context.client_cert is not None:
87115
logger.debug("Enabling mutual authentication as well")
88-
if self._ssl_domain is not None:
89-
self._ssl_domain.set_credentials(
90-
self._conf_ssl_context.client_cert.client_cert,
91-
self._conf_ssl_context.client_cert.client_key,
92-
self._conf_ssl_context.client_cert.password,
116+
117+
if isinstance(self._conf_ssl_context, PosixSslConfigurationContext):
118+
client_cert = self._conf_ssl_context.client_cert.client_cert
119+
client_key = self._conf_ssl_context.client_cert.client_key
120+
password = self._conf_ssl_context.client_cert.password
121+
elif isinstance(self._conf_ssl_context, WinSslConfigurationContext):
122+
client_cert = self._win_store_to_cert(
123+
self._conf_ssl_context.client_cert.store
93124
)
125+
disambiguation_method = (
126+
self._conf_ssl_context.client_cert.disambiguation_method
127+
)
128+
if isinstance(disambiguation_method, Unambiguous):
129+
client_key = None
130+
elif isinstance(disambiguation_method, FriendlyName):
131+
client_key = disambiguation_method.name
132+
else:
133+
typing_extensions.assert_never(disambiguation_method)
134+
135+
password = self._conf_ssl_context.client_cert.password
136+
else:
137+
typing_extensions.assert_never(self._conf_ssl_context)
138+
139+
self._ssl_domain.set_credentials(
140+
client_cert,
141+
client_key,
142+
password,
143+
)
94144
self._conn = BlockingConnection(
95145
url=self._addr,
96146
urls=self._addrs,
@@ -100,6 +150,19 @@ def dial(self) -> None:
100150
self._open()
101151
logger.debug("Connection to the server established")
102152

153+
def _win_store_to_cert(
154+
self, store: Union[LocalMachineStore, CurrentUserStore, PKCS12Store]
155+
) -> str:
156+
if isinstance(store, LocalMachineStore):
157+
ca_cert = f"lmss:{store.name}"
158+
elif isinstance(store, CurrentUserStore):
159+
ca_cert = f"ss:{store.name}"
160+
elif isinstance(store, PKCS12Store):
161+
ca_cert = store.path
162+
else:
163+
typing_extensions.assert_never(store)
164+
return ca_cert
165+
103166
def _open(self) -> None:
104167
self._management = Management(self._conn)
105168
self._management.open()

0 commit comments

Comments
 (0)