|
| 1 | +import base64 |
| 2 | +import hashlib |
1 | 3 | import json
|
| 4 | +import ssl |
2 | 5 | from typing import List
|
3 | 6 |
|
| 7 | +from .utils import DIGEST_HASH |
4 | 8 | from ..exception import UnsupportedAlgorithm
|
| 9 | +from ..utils import as_bytes |
5 | 10 | from ..utils import as_unicode
|
6 | 11 | from ..utils import b64e
|
7 | 12 | from ..utils import base64url_to_long
|
8 |
| -from .utils import DIGEST_HASH |
9 | 13 |
|
10 | 14 | USE = {
|
11 | 15 | 'sign': 'sig',
|
12 | 16 | 'decrypt': 'enc',
|
13 | 17 | 'encrypt': 'enc',
|
14 | 18 | 'verify': 'sig'
|
15 |
| - } |
| 19 | +} |
16 | 20 |
|
17 | 21 |
|
18 | 22 | class JWK(object):
|
@@ -46,7 +50,7 @@ def __init__(self, kty="", alg="", use="", kid="", x5c=None,
|
46 | 50 | # The list comes from https://tools.ietf.org/html/rfc7518#page-6
|
47 | 51 | # Should map against SIGNER_ALGS in cryptojwt.jws.jws
|
48 | 52 | if alg not in ["HS256", "HS384", "HS512", "RS256", "RS384",
|
49 |
| - "RS512", "ES256", "ES384","ES512", "PS256", |
| 53 | + "RS512", "ES256", "ES384", "ES512", "PS256", |
50 | 54 | "PS384", "PS512", "none"]:
|
51 | 55 | raise UnsupportedAlgorithm("Unknown algorithm: {}".format(alg))
|
52 | 56 |
|
@@ -232,3 +236,57 @@ def appropriate_for(self, usage, **kwargs):
|
232 | 236 | return self.use == USE[usage]
|
233 | 237 | elif self.key_ops:
|
234 | 238 | return usage in self.key_ops
|
| 239 | + |
| 240 | + |
| 241 | +def pems_to_x5c(cert_chain): |
| 242 | + """ |
| 243 | + Takes a list of PEM formated certificates and transforms them into a x5c attribute |
| 244 | + values as described in RFC 7517. |
| 245 | +
|
| 246 | + :param cert_pem: List of PKIX certificates |
| 247 | + :return: List of strings |
| 248 | + """ |
| 249 | + |
| 250 | + return [as_unicode(v) for v in |
| 251 | + [base64.b64encode(d) for d in [ssl.PEM_cert_to_DER_cert(c) for c in cert_chain]]] |
| 252 | + |
| 253 | + |
| 254 | +def x5c_to_pems(x5c): |
| 255 | + """ |
| 256 | + Takes a x5c value from a JWK and converts it into a list of PEM formated certificates. |
| 257 | +
|
| 258 | + :param x5c: List of strings |
| 259 | + :return: |
| 260 | + """ |
| 261 | + |
| 262 | + return [ssl.DER_cert_to_PEM_cert(d) for d in |
| 263 | + [base64.b64decode(x) for x in [as_bytes(y) for y in x5c]]] |
| 264 | + |
| 265 | + |
| 266 | +def x5c_to_ders(x5c): |
| 267 | + """ |
| 268 | + Takes a x5c value from a JWK and converts it into a list of PEM formated certificates. |
| 269 | +
|
| 270 | + :param x5c: List of strings |
| 271 | + :return: |
| 272 | + """ |
| 273 | + |
| 274 | + return [base64.b64decode(x) for x in [as_bytes(y) for y in x5c]] |
| 275 | + |
| 276 | + |
| 277 | +def certificate_fingerprint(der, hash="sha256"): |
| 278 | + """ |
| 279 | +
|
| 280 | + :param der: DER encoded certificate |
| 281 | + :return: |
| 282 | + """ |
| 283 | + if hash == "sha256": |
| 284 | + fp = hashlib.sha256(as_bytes(der)).hexdigest() |
| 285 | + elif hash == "sha1": |
| 286 | + fp = hashlib.sha1(as_bytes(der)).hexdigest() |
| 287 | + elif hash == "md5": |
| 288 | + fp = hashlib.md5(as_bytes(der)).hexdigest() |
| 289 | + else: |
| 290 | + raise UnsupportedAlgorithm(hash) |
| 291 | + |
| 292 | + return ':'.join([fp[i:i + 2] for i in range(0, len(fp), 2)]).upper() |
0 commit comments