{"record":{"id":"5b9b6c49f0ad7425","repo":"arduino/Arduino","slug":"empty-or-no-certificate","errorCode":null,"errorMessage":"empty or no certificate","messagePattern":"empty or no certificate","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"arduino-core/src/processing/app/i18n/python/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py","lineNumber":32,"sourceCode":"            # When '*' is a fragment by itself, it matches a non-empty dotless\n            # fragment.\n            pats.append('[^.]+')\n        else:\n            # Otherwise, '*' matches any dotless fragment.\n            frag = re.escape(frag)\n            pats.append(frag.replace(r'\\*', '[^.]*'))\n    return re.compile(r'\\A' + r'\\.'.join(pats) + r'\\Z', re.IGNORECASE)\n\ndef match_hostname(cert, hostname):\n    \"\"\"Verify that *cert* (in decoded format as returned by\n    SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 rules\n    are mostly followed, but IP addresses are not accepted for *hostname*.\n\n    CertificateError is raised on failure. On success, the function\n    returns nothing.\n    \"\"\"\n    if not cert:\n        raise ValueError(\"empty or no certificate\")\n    dnsnames = []\n    san = cert.get('subjectAltName', ())\n    for key, value in san:\n        if key == 'DNS':\n            if _dnsname_to_pat(value).match(hostname):\n                return\n            dnsnames.append(value)\n    if not dnsnames:\n        # The subject is only checked when there is no dNSName entry\n        # in subjectAltName\n        for sub in cert.get('subject', ()):\n            for key, value in sub:\n                # XXX according to RFC 2818, the most specific Common Name\n                # must be used.\n                if key == 'commonName':\n                    if _dnsname_to_pat(value).match(hostname):\n                        return\n                    dnsnames.append(value)","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/arduino/Arduino/blob/a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee/arduino-core/src/processing/app/i18n/python/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py#L14-L50","documentation":"ssl_match_hostname.match_hostname() raises ValueError('empty or no certificate') when the cert argument is falsy — None or an empty dict. A peer certificate dict (typically from SSLSocket.getpeercert()) is required to perform hostname verification; without it there is nothing to match against.","triggerScenarios":"Calling match_hostname(sock.getpeercert(), hostname) when the peer sent no certificate (getpeercert() returns None on unauthenticated sessions) or an empty dict; passing the raw socket instead of the cert dict.","commonSituations":"TLS sessions negotiated without certificate verification or with anonymous cipher suites; forgetting to enable CERT_REQUIRED so the peer cert is never populated; testing harnesses with mock sockets returning None.","solutions":["Check `if not cert:` before calling match_hostname and treat it as a failed/handshake-unverified connection.","Configure the SSL context with CERT_REQUIRED so a peer certificate is always present.","Pass the parsed dict from getpeercert(), not the socket or raw PEM bytes.","Reject connections lacking a certificate rather than proceeding unverified."],"exampleFix":"// before\nmatch_hostname(sock.getpeercert(), hostname)\n// after\ncert = sock.getpeercert()\nif not cert:\n    raise SSLError('no peer certificate presented')\nmatch_hostname(cert, hostname)","handlingStrategy":"validation","validationCode":"cert = sock.getpeercert()\nif not cert:\n    raise SSLError('peer presented no certificate')\nmatch_hostname(cert, hostname)","typeGuard":"def has_peer_certificate(cert):\n    return isinstance(cert, dict) and len(cert) > 0","tryCatchPattern":"try:\n    match_hostname(cert, hostname)\nexcept ValueError as e:\n    if 'empty or no certificate' in str(e):\n        raise SSLError('no certificate to verify') from e\n    raise","preventionTips":["Always configure CERT_REQUIRED so getpeercert() returns a populated dict.","Falsiness-check the cert dict before verification and abort on empty.","Pass the parsed cert dict, never the socket or raw bytes."],"tags":["ssl","tls","certificate","python"],"backgroundTag":"empty-required-field","analyzedSha":"a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee","analyzedAt":"2026-09-06T10:13:38.901Z","contentChangedAt":"2026-09-06T10:13:38.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}