예제 #1
0
/*
 * convert RSA key to JWK JSON string representation and kid
 */
apr_byte_t apr_jwk_to_json(apr_pool_t *pool, apr_jwk_t *jwk, char **s_json,
		apr_jwt_error_t *err) {

	if (jwk->type != APR_JWK_KEY_RSA) {
		apr_jwt_error(err, "non RSA keys (%d) not yet supported", jwk->type);
		return FALSE;
	}

	apr_jwk_key_rsa_t *key = jwk->key.rsa;

	unsigned char *n_enc = NULL;
	int n_len = apr_jwt_base64url_encode(pool, (char **) &n_enc,
			(const char *) key->modulus, key->modulus_len, 0);
	if (n_len <= 0) {
		apr_jwt_error(err, "apr_jwt_base64url_encode of modulus failed");
		return FALSE;
	}

	unsigned char *e_enc = NULL;
	if (apr_jwt_base64url_encode(pool, (char **) &e_enc,
			(const char *) key->exponent, key->exponent_len, 0) <= 0) {
		apr_jwt_error(err,
				"apr_jwt_base64url_encode of public exponent failed");
		return FALSE;
	}

	unsigned char *d_enc = NULL;
	if (key->private_exponent_len > 0) {
		if (apr_jwt_base64url_encode(pool, (char **) &d_enc,
				(const char *) key->private_exponent, key->private_exponent_len,
				0) <= 0) {
			apr_jwt_error(err,
					"apr_jwt_base64url_encode of private exponent failed");
			return FALSE;
		}
	}

	char *p = apr_psprintf(pool, "{ \"kty\" : \"RSA\"");
	p = apr_psprintf(pool, "%s, \"n\": \"%s\"", p, n_enc);
	p = apr_psprintf(pool, "%s, \"e\": \"%s\"", p, e_enc);
	if (d_enc != NULL)
		p = apr_psprintf(pool, "%s, \"d\": \"%s\"", p, d_enc);
	p = apr_psprintf(pool, "%s, \"kid\" : \"%s\"", p, jwk->kid);
	p = apr_psprintf(pool, "%s }", p);

	*s_json = p;

	return TRUE;
}
예제 #2
0
/*
 * convert RSA key to JWK JSON string representation and kid
 */
static apr_byte_t apr_jwk_rsa_to_json(apr_pool_t *pool, apr_jwk_key_rsa_t *key,
		char **jwk, char**kid) {

	unsigned char *n_enc = NULL;
	int n_len = apr_jwt_base64url_encode(pool, (char **) &n_enc,
			(const char *) key->modulus, key->modulus_len, 0);

	unsigned char *e_enc = NULL;
	apr_jwt_base64url_encode(pool, (char **) &e_enc,
			(const char *) key->exponent, key->exponent_len, 0);

	unsigned char *d_enc = NULL;
	if (key->private_exponent_len > 0)
		apr_jwt_base64url_encode(pool, (char **) &d_enc,
				(const char *) key->private_exponent, key->private_exponent_len,
				0);

	/* calculate a unique key identifier (kid) by fingerprinting the key params */
	// TODO: based just on sha1 hash of baseurl-encoded "n" now...
	unsigned int fp_len = SHA_DIGEST_LENGTH;
	unsigned char fp[SHA_DIGEST_LENGTH];
	if (!SHA1(n_enc, n_len, fp))
		return FALSE;
	char *fp_enc = NULL;
	if (apr_jwt_base64url_encode(pool, &fp_enc, (const char *) fp, fp_len,
			0) == FALSE)
		return FALSE;

	char *p = apr_psprintf(pool, "{ \"kty\" : \"RSA\"");
	p = apr_psprintf(pool, "%s, \"n\": \"%s\"", p, n_enc);
	p = apr_psprintf(pool, "%s, \"e\": \"%s\"", p, e_enc);
	if (d_enc != NULL)
		p = apr_psprintf(pool, "%s, \"d\": \"%s\"", p, d_enc);
	p = apr_psprintf(pool, "%s, \"kid\" : \"%s\"", p, fp_enc);
	p = apr_psprintf(pool, "%s }", p);

	*jwk = p;
	*kid = fp_enc;

	return TRUE;
}
예제 #3
0
static char *test_jwt_url_encode_decode(apr_pool_t *pool) {
	char *dst = NULL;
	char *src = "abcd";

	TST_ASSERT("apr_jwt_base64url_encode (1)",
			apr_jwt_base64url_encode(pool, &dst, src, strlen(src), 0));
	TST_ASSERT_STR("apr_jwt_base64url_encode (2)", dst, "YWJjZA");

	src = dst;

	TST_ASSERT("apr_jwt_base64url_decode (1)",
			apr_jwt_base64url_decode(pool, &dst, src, 1));
	TST_ASSERT_STR("apr_jwt_base64url_decode (2)", dst, "abcd");

	return 0;
}
예제 #4
0
/*
 * calculate a hash and base64url encode the result
 */
static apr_byte_t apr_jwk_hash_and_base64urlencode(apr_pool_t *pool,
		const unsigned char *input, const int input_len, char **output,
		apr_jwt_error_t *err) {

	unsigned int hash_len = SHA_DIGEST_LENGTH;
	unsigned char hash[SHA_DIGEST_LENGTH];

	// TODO: upgrade to SHA2?

	/* hash it */
	if (!SHA1(input, input_len, hash)) {
		apr_jwt_error_openssl(err, "SHA1");
		return FALSE;
	}

	/* base64url encode the key fingerprint */
	if (apr_jwt_base64url_encode(pool, output, (const char *) hash, hash_len, 0)
			<= 0) {
		apr_jwt_error(err, "apr_jwt_base64url_encode of hash failed");
		return FALSE;
	}

	return TRUE;
}