function rp_decrypt_verify_id_token($id_token)
{
    $response = array();
    $jwt_parts = jwt_to_array($id_token);
    if (isset($jwt_parts[0]['enc'])) {
        // encrypted
        echo "Encrypted ID Token - {$jwt_parts[0]['enc']} {$jwt_parts[0]['alg']} {$jwt_parts[0]['int']}\n";
        $response['jwe'] = $jwt_parts;
        $signed_jwt = jwt_decrypt($id_token, RP_PKEY, true);
        if (!$signed_jwt) {
            echo "Unable to decrypt ID Token response";
            return false;
        }
    } else {
        // signed
        $signed_jwt = $id_token;
        // echo "Signed ID Token {$jwt_parts[0]['alg']}\n";
    }
    if ($signed_jwt) {
        list($header, $payload, $sig) = jwt_to_array($signed_jwt);
        // echo "Signed ID Token {$header['alg']}\n";
        $response['jws'] = array($header, $payload, $sig);
        if ($header['alg'] == 'none') {
            $verified = true;
        } else {
            $verified = jwt_verify($signed_jwt);
        }
        // echo "Signature Verification = $verified";
        if ($verified) {
            if (isset($payload['address']) && is_array($payload['address'])) {
                if (isset($payload['address']['formatted'])) {
                    $payload['address'] = $payload['address']['formatted'];
                } else {
                    $payload['address'] = "{$payload['address']['street_address']}\n{$payload['address']['locality']}, {$payload['address']['region']} {$payload['address']['postal_code']}\n{$payload['address']['country']}";
                }
            }
            if (isset($payload['aud']) && is_array($payload['aud'])) {
                $payload['aud'] = implode(', ', $payload['aud']);
            }
            $g_id_response = $payload;
            // echo "ID Token Signature Verified\n";
            $_SESSION['login'] = $payload['sub'];
        } else {
            echo "ID Token Signature Verification Failed\n";
        }
    }
    return $response;
}
/**
 * Decrypts and Verifies a JWT
 * @param $jwt
 * @param $client Array Client Info
 * @param $error  String error code error_decrypt or error_sig
 * @return mixed null/decoded payload
 */
function decrypt_verify_jwt($jwt, $client, &$error)
{
    $response = NULL;
    $jwt_parts = jwt_to_array($jwt);
    if (isset($jwt_parts[0]['enc'])) {
        // encrypted
        $signed_jwt = jwt_decrypt($jwt, OP_ENC_PKEY, true, OP_ENC_PKEY_PASSPHRASE);
        if (!$signed_jwt) {
            log_error('Unable to decrypt object');
            $error = 'error_decrypt';
            return NULL;
        } else {
            log_debug("decrypted object = %s", $signed_jwt);
        }
    } else {
        $signed_jwt = $jwt;
    }
    if ($signed_jwt) {
        list($header, $payload, $sig) = jwt_to_array($signed_jwt);
        $verified = false;
        if (substr($header['alg'], 0, 2) == 'HS') {
            $verified = jwt_verify($signed_jwt, $client['client_secret']);
        } elseif (substr($header['alg'], 0, 2) == 'RS') {
            $pubkeys = array();
            if ($client['jwks_uri']) {
                $pubkeys['jku'] = $client['jwks_uri'];
            }
            if ($client['jwks']) {
                $pubkeys['jwk'] = $client['jwks'];
            }
            $verified = jwt_verify($signed_jwt, $pubkeys);
        } elseif ($header['alg'] == 'none') {
            $verified = true;
        }
        log_debug("Signature Verification = {$verified}");
        if ($verified) {
            $response = $payload;
        } else {
            $error = 'error_sig';
        }
    }
    return $response;
}
function rp_decrypt_verify_id_token($id_token)
{
    global $g_id_response, $g_info, $g_error;
    $response = array();
    $jwt_parts = jwt_to_array($id_token);
    if (isset($jwt_parts[0]['enc'])) {
        // encrypted
        $g_info .= "Encrypted ID Token - {$jwt_parts[0]['enc']} {$jwt_parts[0]['alg']} {$jwt_parts[0]['int']}\n";
        $response['jwe'] = $jwt_parts;
        $signed_jwt = jwt_decrypt($id_token, RP_ENC_PKEY, true, RP_ENC_PKEY_PASSPHRASE);
        if (!$signed_jwt) {
            $g_error .= "Unable to decrypt ID Token response";
            log_error('%s', $g_error);
            return;
        }
    } else {
        // signed
        $signed_jwt = $id_token;
        $g_info .= "Signed ID Token {$jwt_parts[0]['alg']}\n";
    }
    if ($signed_jwt) {
        list($header, $payload, $sig) = jwt_to_array($signed_jwt);
        $g_info .= "Signed ID Token {$header['alg']}\n";
        $response['jws'] = array($header, $payload, $sig);
        if (substr($header['alg'], 0, 2) == 'HS') {
            $verified = jwt_verify($signed_jwt, $_SESSION['provider']['client_secret']);
        } elseif (substr($header['alg'], 0, 2) == 'RS') {
            $pubkeys = array();
            if ($_SESSION['provider']['jwks_uri']) {
                $pubkeys['jku'] = $_SESSION['provider']['jwks_uri'];
            }
            $verified = jwt_verify($signed_jwt, $pubkeys);
        } elseif ($header['alg'] == 'none') {
            $verified = true;
        }
        log_info("Signature Verification = %d", $verified);
        if ($verified) {
            if (isset($payload['address']) && is_array($payload['address'])) {
                if (isset($payload['address']['formatted'])) {
                    $payload['address'] = $payload['address']['formatted'];
                } else {
                    $payload['address'] = "{$payload['address']['street_address']}\n{$payload['address']['locality']}, {$payload['address']['region']} {$payload['address']['postal_code']}\n{$payload['address']['country']}";
                }
            }
            if (isset($payload['aud']) && is_array($payload['aud'])) {
                $payload['aud'] = implode(', ', $payload['aud']);
            }
            $g_id_response = $payload;
            $g_info .= "ID Token Signature Verified\n";
            $_SESSION['id_token'] = $signed_jwt;
        } else {
            $g_info .= "ID Token Signature Verification Failed\n";
        }
    }
    return $response;
}