Skip to content

Commit

Permalink
5.7.1
Browse files Browse the repository at this point in the history
- Properly parse a certificate SAN
- Certificate warnings fire properly
  • Loading branch information
seanthegeek committed Oct 29, 2024
1 parent 72d8eee commit a8d15eb
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 14 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Changelog
=========

7.5.1
-----

- Properly parse a certificate SAN
- Certificate warnings fire properly

5.7.0
-----

Expand Down
2 changes: 1 addition & 1 deletion checkdmarc/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
See the License for the specific language governing permissions and
limitations under the License."""

__version__ = "5.7.0"
__version__ = "5.7.1"

OS = platform.system()
OS_RELEASE = platform.release()
Expand Down
26 changes: 13 additions & 13 deletions checkdmarc/bimi.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,18 +227,17 @@ def check_svg_requirements(svg_metadata: OrderedDict) -> [str]:
return _warnings


def _get_certificate_subjecttaltnames(cert: Union[X509, bytes]) -> [str]:
def _get_certificate_san(cert: Union[X509, bytes]) -> [str]:
"""Get the subjectaltname from a PEM certificate"""
if type(cert) is bytes:
cert = load_certificate(FILETYPE_PEM, cert)
for cert_ext_id in range(cert.get_extension_count()):
cert_ext = cert.get_extension(cert_ext_id)
if cert_ext.get_short_name() == b"subjectAltName":
ext_data = (
cert_ext.get_data().strip(b"0\x10\x82\x0e").strip(b"0\x81\x8e\x82\x13")
)
return ext_data.decode("utf-8", errors="ignore").lower().split("\x82\x15")

san = cert_ext.__str__()
san.replace("DNS:", "")
san = san.split(", ")
return san

def extract_logo_from_certificate(cert: Union[bytes, X509]):
"""Extracts the logo from a certificate"""
Expand All @@ -258,7 +257,7 @@ def get_certificate_metadata(pem_crt: Union[str, bytes], domain=None) -> Ordered
metadata = OrderedDict()
valid = False
validation_errors = []
subjectaltnames = []
san = []

def decode_components(components: dict):
new_dict = OrderedDict()
Expand All @@ -281,8 +280,8 @@ def decode_components(components: dict):
metadata["serial_number"] = vmc.get_serial_number()
metadata["expires"] = str(vmc.get_notAfter())
metadata["valid"] = valid and not vmc.has_expired()
subjectaltnames = _get_certificate_subjecttaltnames(vmc)
metadata["domains"] = subjectaltnames
san = _get_certificate_san(vmc)
metadata["domains"] = san
metadata["logodata_sha256_hash"] = None
logodata = extract_logo_from_certificate(vmc)
if logodata is not None:
Expand All @@ -298,9 +297,9 @@ def decode_components(components: dict):
except Exception as e:
validation_errors.append(str(e))
if domain is not None:
if domain.lower() not in subjectaltnames:
if domain.lower() not in san:
validation_errors.append(
f"{domain} does not match the certificate subjectaltnames, {subjectaltnames}"
f"{domain} does not match the certificate san, {san}"
)
metadata["validation_errors"] = validation_errors
metadata["valid"] = False
Expand Down Expand Up @@ -565,18 +564,19 @@ def parse_bimi_record(
response.raise_for_status()
pem_bytes = response.content
cert_metadata = get_certificate_metadata(pem_bytes, domain=domain)
hash_match = False
if (
image_metadata["sha256_hash"]
== cert_metadata["logodata_sha256_hash"]
):
certificate_provided = True
hash_match = True
else:
warnings.append(
"SHA256 hash mismatch between the certificate and the image"
)
except Exception as e:
warnings.append(f"Unable to download mark certificate - {str(e)}")

certificate_provided == hash_match and cert_metadata["valid"]
if not certificate_provided:
warnings.append(
"Most providers will not display a BIMI image without a valid mark certificate"
Expand Down

0 comments on commit a8d15eb

Please sign in to comment.