|
21 | 21 |
|
22 | 22 |
|
23 | 23 | # The __init__.py will import this. Not the other way around.
|
24 |
| -__version__ = "1.5.1" |
| 24 | +__version__ = "1.6.0" |
25 | 25 |
|
26 | 26 | logger = logging.getLogger(__name__)
|
27 | 27 |
|
@@ -90,6 +90,14 @@ def _merge_claims_challenge_and_capabilities(capabilities, claims_challenge):
|
90 | 90 | return json.dumps(claims_dict)
|
91 | 91 |
|
92 | 92 |
|
| 93 | +def _str2bytes(raw): |
| 94 | + # A conversion based on duck-typing rather than six.text_type |
| 95 | + try: |
| 96 | + return raw.encode(encoding="utf-8") |
| 97 | + except: |
| 98 | + return raw |
| 99 | + |
| 100 | + |
93 | 101 | class ClientApplication(object):
|
94 | 102 |
|
95 | 103 | ACQUIRE_TOKEN_SILENT_ID = "84"
|
@@ -123,7 +131,8 @@ def __init__(
|
123 | 131 | {
|
124 | 132 | "private_key": "...-----BEGIN PRIVATE KEY-----...",
|
125 | 133 | "thumbprint": "A1B2C3D4E5F6...",
|
126 |
| - "public_certificate": "...-----BEGIN CERTIFICATE-----..." (Optional. See below.) |
| 134 | + "public_certificate": "...-----BEGIN CERTIFICATE-----... (Optional. See below.)", |
| 135 | + "passphrase": "Passphrase if the private_key is encrypted (Optional. Added in version 1.6.0)", |
127 | 136 | }
|
128 | 137 |
|
129 | 138 | *Added in version 0.5.0*:
|
@@ -252,8 +261,18 @@ def _build_client(self, client_credential, authority):
|
252 | 261 | headers = {}
|
253 | 262 | if 'public_certificate' in client_credential:
|
254 | 263 | headers["x5c"] = extract_certs(client_credential['public_certificate'])
|
| 264 | + if not client_credential.get("passphrase"): |
| 265 | + unencrypted_private_key = client_credential['private_key'] |
| 266 | + else: |
| 267 | + from cryptography.hazmat.primitives import serialization |
| 268 | + from cryptography.hazmat.backends import default_backend |
| 269 | + unencrypted_private_key = serialization.load_pem_private_key( |
| 270 | + _str2bytes(client_credential["private_key"]), |
| 271 | + _str2bytes(client_credential["passphrase"]), |
| 272 | + backend=default_backend(), # It was a required param until 2020 |
| 273 | + ) |
255 | 274 | assertion = JwtAssertionCreator(
|
256 |
| - client_credential["private_key"], algorithm="RS256", |
| 275 | + unencrypted_private_key, algorithm="RS256", |
257 | 276 | sha1_thumbprint=client_credential.get("thumbprint"), headers=headers)
|
258 | 277 | client_assertion = assertion.create_regenerative_assertion(
|
259 | 278 | audience=authority.token_endpoint, issuer=self.client_id,
|
|
0 commit comments