def extract_subjects(cert_pem):
    """Extract subjects from a DataONE PEM (Base64) encoded X.509 v3 certificate.

    Args:
      cert_pem: str or bytes
        PEM (Base64) encoded X.509 v3 certificate

    Returns:
      2-tuple:
        - The primary subject string, extracted from the certificate DN.
        - A set of equivalent identities, group memberships and inferred symbolic
          subjects extracted from the SubjectInfo (if present.)
        - All returned subjects are DataONE compliant serializations.
        - A copy of the primary subject is always included in the set of equivalent
          identities.

    """
    primary_str, subject_info_xml = d1_common.cert.x509.extract_subjects(cert_pem)
    equivalent_set = {
        primary_str,
        d1_common.const.SUBJECT_AUTHENTICATED,
        d1_common.const.SUBJECT_PUBLIC,
    }
    if subject_info_xml is not None:
        equivalent_set |= d1_common.cert.subject_info.extract_subjects(
            subject_info_xml, primary_str
        )
    return primary_str, equivalent_set