Skip to content

Commit

Permalink
Deprecate and add new encoding and decoding functions
Browse files Browse the repository at this point in the history
  • Loading branch information
ohemorange committed Jan 15, 2025
1 parent 428c31c commit 17a3e5b
Showing 1 changed file with 75 additions and 11 deletions.
86 changes: 75 additions & 11 deletions src/josepy/json_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import abc
import binascii
import logging
import warnings
from typing import (
Any,
Callable,
Expand All @@ -20,8 +21,11 @@
Optional,
Type,
TypeVar,
Union,
)

from cryptography import x509
from cryptography.hazmat.primitives.serialization import Encoding
from OpenSSL import crypto

from josepy import b64, errors, interfaces, util
Expand Down Expand Up @@ -426,26 +430,41 @@ def decode_hex16(value: str, size: Optional[int] = None, minimum: bool = False)
raise errors.DeserializationError(error)


def encode_cert(cert: util.ComparableX509) -> str:
def encode_cert(cert: Union[util.ComparableX509, x509.Certificate]) -> str:
"""Encode certificate as JOSE Base-64 DER.
:type cert: `OpenSSL.crypto.X509` wrapped in `.ComparableX509`
:type cert: `cryptography.x509.Certificate`
or `OpenSSL.crypto.X509` wrapped in `.ComparableX509`
:rtype: unicode
"""
if isinstance(cert.wrapped, crypto.X509Req):
raise ValueError("Error input is actually a certificate request.")

return encode_b64jose(crypto.dump_certificate(crypto.FILETYPE_ASN1, cert.wrapped))
if isinstance(cert, util.ComparableX509):
# DEPRECATED; remove this in major release
warnings.warn(
"`josepy.json_util.encode_cert` has deprecated support for accepting "
"util.ComparableX509 objects, and support will be dropped in the next major release. "
"Please use `cryptography.x509.Certificate` objects instead.",
DeprecationWarning,
)
if isinstance(cert.wrapped, crypto.X509Req):
raise ValueError("Error input is actually a certificate request.")
return encode_b64jose(crypto.dump_certificate(crypto.FILETYPE_ASN1, cert.wrapped))
assert isinstance(cert, x509.Certificate)
return encode_b64jose(cert.public_bytes(Encoding.DER))


def decode_cert(b64der: str) -> util.ComparableX509:
"""Decode JOSE Base-64 DER-encoded certificate.
"""Decode JOSE Base-64 DER-encoded certificate. Deprecated as of 1.15.0 and will be
removed in 2.0.0.
:param unicode b64der:
:rtype: `OpenSSL.crypto.X509` wrapped in `.ComparableX509`
"""
warnings.warn(
"`josepy.json_util.decode_cert` is deprecated, and will be removed in the next major "
"release. Please use `josepy.json_util.decode_cert_cryptography instead.",
DeprecationWarning,
)
try:
return util.ComparableX509(
crypto.load_certificate(crypto.FILETYPE_ASN1, decode_b64jose(b64der))
Expand All @@ -454,10 +473,23 @@ def decode_cert(b64der: str) -> util.ComparableX509:
raise errors.DeserializationError(error)


def encode_csr(csr: util.ComparableX509) -> str:
def decode_cert_cryptography(b64der: str) -> x509.Certificate:
"""Decode JOSE Base-64 DER-encoded certificate.
:param unicode b64der:
:rtype: `cryptography.x509.Certificate`
"""
try:
return x509.load_der_x509_certificate(decode_b64jose(b64der))
except Exception as error:
raise errors.DeserializationError(error)


def encode_csr(csr: Union[util.ComparableX509, x509.CertificateSigningRequest]) -> str:
"""Encode CSR as JOSE Base-64 DER.
:type csr: `OpenSSL.crypto.X509Req` wrapped in `.ComparableX509`
:type csr: `cryptography.x509.CertificateSigningRequest`
or `OpenSSL.crypto.X509` wrapped in `.ComparableX509`
:rtype: unicode
"""
Expand All @@ -466,14 +498,33 @@ def encode_csr(csr: util.ComparableX509) -> str:

return encode_b64jose(crypto.dump_certificate_request(crypto.FILETYPE_ASN1, csr.wrapped))

if isinstance(csr, util.ComparableX509):
# DEPRECATED; remove this in major release
warnings.warn(
"`josepy.json_util.encode_csr` has deprecated support for accepting "
"util.ComparableX509 objects, and support will be dropped in the next major release. "
"Please use `cryptography.x509.CertificateSigningRequest` objects instead.",
DeprecationWarning,
)
if isinstance(csr.wrapped_new, x509.Certificate):
raise ValueError("Error input is actually a certificate.")
return encode_b64jose(crypto.dump_certificate_request(crypto.FILETYPE_ASN1, csr.wrapped))
assert isinstance(csr, x509.CertificateSigningRequest)
return encode_b64jose(csr.public_bytes(Encoding.DER))


def decode_csr(b64der: str) -> util.ComparableX509:
"""Decode JOSE Base-64 DER-encoded CSR.
"""Decode JOSE Base-64 DER-encoded CSR. Deprecated as of 1.15.0 and will be removed in 2.0.0.
:param unicode b64der:
:rtype: `OpenSSL.crypto.X509Req` wrapped in `.ComparableX509`
"""
warnings.warn(
"`josepy.json_util.decode_csr` is deprecated, and will be removed in the next major "
"release. Please use `josepy.json_util.decode_csr_cryptography instead.",
DeprecationWarning,
)
try:
return util.ComparableX509(
crypto.load_certificate_request(crypto.FILETYPE_ASN1, decode_b64jose(b64der))
Expand All @@ -482,6 +533,19 @@ def decode_csr(b64der: str) -> util.ComparableX509:
raise errors.DeserializationError(error)


def decode_csr_cryptography(b64der: str) -> x509.CertificateSigningRequest:
"""Decode JOSE Base-64 DER-encoded CSR.
:param unicode b64der:
:rtype: `cryptography.x509.CertificateSigningRequest`
"""
try:
return x509.load_der_x509_csr(decode_b64jose(b64der))
except Exception as error:
raise errors.DeserializationError(error)


GenericTypedJSONObjectWithFields = TypeVar(
"GenericTypedJSONObjectWithFields", bound="TypedJSONObjectWithFields"
)
Expand Down

0 comments on commit 17a3e5b

Please sign in to comment.