Beispiel #1
0
/*
 * parse a JSON Web Token
 */
apr_byte_t apr_jwt_parse(apr_pool_t *pool, const char *s_json,
                         apr_jwt_t **j_jwt, apr_hash_t *private_keys, const char *shared_key) {

    *j_jwt = apr_pcalloc(pool, sizeof(apr_jwt_t));
    apr_jwt_t *jwt = *j_jwt;

    apr_array_header_t *unpacked = apr_jwt_compact_deserialize(pool, s_json);
    if (unpacked->nelts < 2)
        return FALSE;

    /* parse the header fields */
    if (apr_jwt_parse_header(pool, ((const char**) unpacked->elts)[0],
                             &jwt->header) == FALSE)
        return FALSE;

    if (apr_jwe_is_encrypted_jwt(pool, &jwt->header)) {
        char *decrypted = NULL;
        if ((apr_jwe_decrypt_jwt(pool, &jwt->header, unpacked, private_keys,
                                 shared_key, &decrypted) == FALSE) || (decrypted == NULL))
            return FALSE;
        apr_array_clear(unpacked);
        unpacked = apr_jwt_compact_deserialize(pool, (const char *) decrypted);
        json_decref(jwt->header.value.json);
        if (unpacked->nelts < 2)
            return FALSE;
        /* parse the nested header fields */
        if (apr_jwt_parse_header(pool, ((const char**) unpacked->elts)[0],
                                 &jwt->header) == FALSE)
            return FALSE;
    }

    /* concat the base64url-encoded payload to the base64url-encoded header for signature verification purposes */
    jwt->message = apr_pstrcat(pool, ((const char**) unpacked->elts)[0], ".",
                               ((const char**) unpacked->elts)[1], NULL);

    /* parse the payload fields */
    if (apr_jwt_parse_payload(pool, ((const char**) unpacked->elts)[1],
                              &jwt->payload) == FALSE) {
        json_decref(jwt->header.value.json);
        return FALSE;
    }

    if (unpacked->nelts > 2 && strcmp(jwt->header.alg, "none") != 0) {
        /* remainder is the signature */
        if (apr_jwt_parse_signature(pool, ((const char**) unpacked->elts)[2],
                                    &jwt->signature) == FALSE) {
            json_decref(jwt->header.value.json);
            json_decref(jwt->payload.value.json);
            return FALSE;
        }
    }

    return TRUE;
}
Beispiel #2
0
/*
 * parse and (optionally) decrypt a JSON Web Token
 */
apr_byte_t apr_jwt_parse(apr_pool_t *pool, const char *s_json,
		apr_jwt_t **j_jwt, apr_hash_t *keys, apr_jwt_error_t *err) {

	*j_jwt = apr_pcalloc(pool, sizeof(apr_jwt_t));
	apr_jwt_t *jwt = *j_jwt;

	apr_array_header_t *unpacked = NULL;
	if (apr_jwt_header_parse(pool, s_json, &unpacked, &jwt->header,
			err) == FALSE)
		return FALSE;

	if (unpacked->nelts < 2) {
		apr_jwt_error(err,
				"could not successfully deserialize 2 or more elements from JWT header");
		return FALSE;
	}

	if (apr_jwe_is_encrypted_jwt(pool, &jwt->header)) {

		char *decrypted = NULL;
		if ((apr_jwe_decrypt_jwt(pool, &jwt->header, unpacked, keys, &decrypted,
				err) == FALSE) || (decrypted == NULL))
			return FALSE;

		apr_array_clear(unpacked);
		unpacked = NULL;
		json_decref(jwt->header.value.json);

		if (apr_jwt_header_parse(pool, (const char *) decrypted, &unpacked,
				&jwt->header, err) == FALSE)
			return FALSE;

		if (unpacked->nelts < 2) {
			apr_jwt_error(err,
					"could not successfully deserialize 2 or more elements from decrypted JWT header");
			return FALSE;
		}
	}

	/* concat the base64url-encoded payload to the base64url-encoded header for signature verification purposes */
	jwt->message = apr_pstrcat(pool, ((const char**) unpacked->elts)[0], ".",
			((const char**) unpacked->elts)[1], NULL);

	/* parse the payload fields */
	if (apr_jwt_parse_payload(pool, ((const char**) unpacked->elts)[1],
			&jwt->payload, err) == FALSE) {
		json_decref(jwt->header.value.json);
		return FALSE;
	}

	if (unpacked->nelts > 2 && strcmp(jwt->header.alg, "none") != 0) {
		/* remainder is the signature */
		if (apr_jwt_parse_signature(pool, ((const char**) unpacked->elts)[2],
				&jwt->signature) == FALSE) {
			json_decref(jwt->header.value.json);
			json_decref(jwt->payload.value.json);
			apr_jwt_error(err,
					"could not successfully parse (base64urldecode) JWT signature");
			return FALSE;
		}
	}

	return TRUE;
}