コード例 #1
0
/*
 * check a provided hash value (at_hash|c_hash) against a corresponding hash calculated for a specified value and algorithm
 */
static apr_byte_t oidc_proto_validate_hash(request_rec *r, const char *alg,
		const char *hash, const char *value, const char *type) {

	/* hash the provided access_token */
	char *calc = NULL;
	unsigned int hash_len = 0;
	apr_jws_hash_string(r->pool, alg, value, &calc, &hash_len);

	/* calculate the base64url-encoded value of the hash */
	char *encoded = NULL;
	oidc_base64url_encode(r, &encoded, calc, apr_jws_hash_length(alg) / 2, 1);

	/* compare the calculated hash against the provided hash */
	if ((apr_strnatcmp(encoded, hash) != 0)) {
		oidc_error(r,
				"provided \"%s\" hash value (%s) does not match the calculated value (%s)",
				type, hash, encoded);
		return FALSE;
	}

	oidc_debug(r,
			"successfully validated the provided \"%s\" hash value (%s) against the calculated value (%s)",
			type, hash, encoded);

	return TRUE;
}
コード例 #2
0
ファイル: proto.c プロジェクト: jisqyv/mod_auth_openidc
/*
 * check a provided hash value (at_hash|c_hash) against a corresponding hash calculated for a specified value and algorithm
 */
static apr_byte_t oidc_proto_validate_hash(request_rec *r, const char *alg,
		const char *hash, const char *value, const char *type) {

	/* hash the provided access_token */
	char *calc = NULL;
	unsigned int hash_len = 0;
	apr_jws_hash_string(r->pool, alg, value, &calc, &hash_len);

	/* calculate the base64url-encoded value of the hash */
	char *encoded = NULL;
	int enc_len = oidc_base64url_encode(r, &encoded, calc,
			apr_jws_hash_length(alg) / 2);

	/* remove /0 and padding */
	enc_len--;
	if (encoded[enc_len - 1] == ',')
		enc_len--;
	if (encoded[enc_len - 1] == ',')
		enc_len--;

	/* compare the calculated hash against the provided hash */
	if ((strncmp(encoded, hash, enc_len) != 0)) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
				"oidc_proto_validate_hash: provided \"%s\" hash value (%s) does not match the calculated value (%s)",
				type, hash, encoded);
		return FALSE;
	}

	ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
			"oidc_proto_validate_hash: successfully validated the provided \"%s\" hash value (%s) against the calculated value (%s)",
			type, hash, encoded);

	return TRUE;
}
コード例 #3
0
/*
 * generate a random value (nonce) to correlate request/response through browser state
 */
apr_byte_t oidc_proto_generate_nonce(request_rec *r, char **nonce) {
	unsigned char *nonce_bytes = apr_pcalloc(r->pool, OIDC_PROTO_NONCE_LENGTH);
	if (apr_generate_random_bytes(nonce_bytes,
			OIDC_PROTO_NONCE_LENGTH) != APR_SUCCESS) {
		oidc_error(r, "apr_generate_random_bytes returned an error");
		return FALSE;
	}
	if (oidc_base64url_encode(r, nonce, (const char *) nonce_bytes,
			OIDC_PROTO_NONCE_LENGTH, TRUE) <= 0) {
		oidc_error(r, "oidc_base64url_encode returned an error");
		return FALSE;
	}
	return TRUE;
}
コード例 #4
0
ファイル: test.c プロジェクト: bester/mod_auth_openidc
static char * test_proto_validate_jwt(request_rec *r) {

	apr_jwt_t *jwt = NULL;
	apr_jwt_error_t err;

	const char *s_secret = "secret";
	const char *s_issuer = "https://localhost";
	apr_time_t now = apr_time_sec(apr_time_now());

	const char *s_jwt_header = "{"
			"\"alg\": \"HS256\""
			"}";

	const char *s_jwt_payload = "{"
			"\"nonce\": \"543210,\","
			"\"iat\": %" APR_TIME_T_FMT ","
			"\"sub\": \"alice\","
			"\"iss\": \"%s\","
			"\"aud\": \"bob\","
			"\"exp\": %" APR_TIME_T_FMT
			"}";
	s_jwt_payload = apr_psprintf(r->pool, s_jwt_payload, now, s_issuer,
			now + 600);

	char *s_jwt_header_encoded = NULL;
	oidc_base64url_encode(r, &s_jwt_header_encoded, s_jwt_header,
			strlen(s_jwt_header), 1);

	char *s_jwt_payload_encoded = NULL;
	oidc_base64url_encode(r, &s_jwt_payload_encoded, s_jwt_payload,
			strlen(s_jwt_payload), 1);

	char *s_jwt_message = apr_psprintf(r->pool, "%s.%s", s_jwt_header_encoded,
			s_jwt_payload_encoded);

	unsigned int md_len = 0;
	unsigned char md[EVP_MAX_MD_SIZE];
	const EVP_MD *digest = EVP_get_digestbyname("sha256");

	TST_ASSERT("HMAC",
			HMAC(digest, (const unsigned char * )s_secret, strlen(s_secret),
					(const unsigned char * )s_jwt_message,
					strlen(s_jwt_message), md, &md_len) != 0);

	char *s_jwt_signature_encoded = NULL;
	oidc_base64url_encode(r, &s_jwt_signature_encoded, (const char *) md,
			md_len, 1);

	char *s_jwt = apr_psprintf(r->pool, "%s.%s.%s", s_jwt_header_encoded,
			s_jwt_payload_encoded, s_jwt_signature_encoded);

	TST_ASSERT_ERR("apr_jwt_parse",
			apr_jwt_parse(r->pool, s_jwt, &jwt, NULL, &err), r->pool, err);

	TST_ASSERT_ERR("apr_jws_verify",
			apr_jws_verify(r->pool, jwt, oidc_util_merge_symmetric_key(r->pool, NULL, s_secret, NULL), &err),
			r->pool, err);

	TST_ASSERT_ERR("oidc_proto_validate_jwt",
			oidc_proto_validate_jwt(r, jwt, s_issuer, TRUE, TRUE, 10), r->pool,
			err);

	apr_jwt_destroy(jwt);

	return 0;
}