Esempio n. 1
0
/*
 * return plain deserialized header text
 */
const char *apr_jwt_header_to_string(apr_pool_t *pool, const char *s_json,
		apr_jwt_error_t *err) {
	apr_array_header_t *unpacked = NULL;
	apr_jwt_header_t header;
	if (apr_jwt_header_parse(pool, s_json, &unpacked, &header, err) == FALSE)
		return NULL;
	json_decref(header.value.json);
	return header.value.str;
}
Esempio n. 2
0
static char *test_plaintext_decrypt(apr_pool_t *pool) {

	// from http://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-30
	// A.2.  Example JWE using RSAES-PKCS1-V1_5 and AES_128_CBC_HMAC_SHA_256
	char *s =
			apr_pstrdup(pool,
					"eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0"
					".UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7PcHALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIFNPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv-B3oWh2TbqmScqXMR4gp_A"
					".AxY8DCtDaGlsbGljb3RoZQ"
					".KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY"
					".9hH0vgRfYgPnAHOd8stkvw");

	char * k =
			"{\"kty\":\"RSA\","
			"\"n\":\"sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1WlUzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDprecbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBIY2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw\","
			"\"e\":\"AQAB\","
			"\"d\":\"VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-rynq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-KyvjT1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ\""
			"}";

	apr_jwt_error_t err;
	apr_hash_t *keys = apr_hash_make(pool);
	apr_jwk_t *jwk = NULL;

	TST_ASSERT_ERR("apr_jwk_parse_json", _jwk_parse(pool, k, &jwk, &err) == 0,
			pool, err);
	apr_hash_set(keys, "dummy", APR_HASH_KEY_STRING, jwk);

	apr_array_header_t *unpacked = NULL;
	apr_jwt_header_t header;
	memset(&header, 0, sizeof(header));
	TST_ASSERT_ERR("apr_jwt_header_parse",
			apr_jwt_header_parse(pool, s, &unpacked, &header, &err), pool, err);

	char *decrypted = NULL;
	TST_ASSERT_ERR("apr_jwe_decrypt_jwt",
			apr_jwe_decrypt_jwt(pool, &header, unpacked, keys, &decrypted,
					&err), pool, err);

	TST_ASSERT_STR("decrypted", decrypted, "Live long and prosper.");

	json_decref(header.value.json);

	return 0;
}
Esempio n. 3
0
static char *test_plaintext_decrypt_symmetric(apr_pool_t *pool) {
	apr_jwt_error_t err;
	apr_hash_t *keys = apr_hash_make(pool);
	apr_jwk_t *jwk;

	// http://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-40#appendix-A.3
	// A.3.  Example JWE using AES Key Wrap and AES_128_CBC_HMAC_SHA_256
	const char * k = "{\"kty\":\"oct\", \"k\":\"GawgguFyGrWKav7AX4VKUg\"}";
	jwk = NULL;
	TST_ASSERT_ERR("apr_jwk_parse_json", _jwk_parse(pool, k, &jwk, &err) == 0,
			pool, err);
	apr_hash_set(keys, "dummy", APR_HASH_KEY_STRING, jwk);

	const char *s = "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0."
			"6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ."
			"AxY8DCtDaGlsbGljb3RoZQ."
			"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY."
			"U0m_YmjN04DJvceFICbCVQ";

	apr_array_header_t *unpacked = NULL;
	apr_jwt_header_t header;
	memset(&header, 0, sizeof(header));
	TST_ASSERT_ERR("apr_jwt_header_parse",
			apr_jwt_header_parse(pool, s, &unpacked, &header, &err), pool, err);

	char *decrypted = NULL;
	TST_ASSERT_ERR("apr_jwe_decrypt_jwt",
			apr_jwe_decrypt_jwt(pool, &header, unpacked, keys, &decrypted,
					&err), pool, err);

	TST_ASSERT_STR("decrypted", decrypted, "Live long and prosper.");

	json_decref(header.value.json);

	return 0;
}
Esempio n. 4
0
static char *test_jwt_decrypt_gcm(apr_pool_t *pool) {

	// https://tools.ietf.org/html/rfc7516#appendix-A.1
	// A.1.  Example JWE using RSAES-OAEP and AES GCM
	char * s =
			apr_pstrdup(pool,
					"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ."
					"OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGe"
					"ipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDb"
					"Sv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaV"
					"mqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je8"
					"1860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi"
					"6UklfCpIMfIjf7iGdXKHzg."
					"48V1_ALb6US04U3b."
					"5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6ji"
					"SdiwkIr3ajwQzaBtQD_A."
					"XFBoMYUZodetZdvTiFvSkQ");

	char * k =
			"{\"kty\":\"RSA\","
			"\"n\":\"oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW"
			  "cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S"
			  "psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a"
			  "sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS"
			  "tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj"
			  "YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw\","
			"\"e\":\"AQAB\","
			"\"d\":\"kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N"
			  "WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9"
			  "3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk"
			  "qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl"
			  "t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd"
			  "VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ\","
			"\"p\":\"1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ-"
			  "SWxkbkmoEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lf"
			  "fNn03IXqWF5MDFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0\","
			"\"q\":\"wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBm"
			  "UDdaDYVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aX"
			  "IWxKwd4gvxFImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc\","
			"\"dp\":\"ZK-YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KL"
			  "hMXvo-uz-KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827"
			  "rnpZzAJKpdhWAgqrXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE\","
			"\"dq\":\"Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCj"
			  "ywcMlYYg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDB"
			  "UfCAiJVeESOjJDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis\","
			"\"qi\":\"VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8-ZW1FxU7"
			  "AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E3"
			  "eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY\""
			"}";

	apr_jwt_error_t err;
	apr_hash_t *keys = apr_hash_make(pool);
	apr_jwk_t *jwk = NULL;
	TST_ASSERT_ERR("apr_jwk_parse_json", _jwk_parse(pool, k, &jwk, &err) == 0,
			pool, err);
	apr_hash_set(keys, "dummy", APR_HASH_KEY_STRING, jwk);

	apr_array_header_t *unpacked = NULL;
	apr_jwt_header_t header;
	memset(&header, 0, sizeof(header));
	TST_ASSERT_ERR("apr_jwt_header_parse",
			apr_jwt_header_parse(pool, s, &unpacked, &header, &err), pool, err);

	char *decrypted = NULL;
	TST_ASSERT_ERR("apr_jwe_decrypt_jwt",
			apr_jwe_decrypt_jwt(pool, &header, unpacked, keys, &decrypted,
					&err), pool, err);

	TST_ASSERT_STR("decrypted", decrypted, "The true sign of intelligence is not knowledge but imagination.");
	TST_ASSERT_STR("header.alg", header.alg, "RSA-OAEP");

	json_decref(header.value.json);

	return 0;
}
Esempio n. 5
0
static char *test_plaintext_decrypt2(apr_pool_t *pool) {

	// http://tools.ietf.org/html/draft-ietf-jose-cookbook-08#section-5.1.5
	// 5.1.  Key Encryption using RSA v1.5 and AES-HMAC-SHA2
	char *s =
			apr_pstrdup(pool,
					"eyJhbGciOiJSU0ExXzUiLCJraWQiOiJmcm9kby5iYWdnaW5zQGhvYmJpdG9uLm"
					"V4YW1wbGUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0"
					"."
					"laLxI0j-nLH-_BgLOXMozKxmy9gffy2gTdvqzfTihJBuuzxg0V7yk1WClnQePF"
					"vG2K-pvSlWc9BRIazDrn50RcRai__3TDON395H3c62tIouJJ4XaRvYHFjZTZ2G"
					"Xfz8YAImcc91Tfk0WXC2F5Xbb71ClQ1DDH151tlpH77f2ff7xiSxh9oSewYrcG"
					"TSLUeeCt36r1Kt3OSj7EyBQXoZlN7IxbyhMAfgIe7Mv1rOTOI5I8NQqeXXW8Vl"
					"zNmoxaGMny3YnGir5Wf6Qt2nBq4qDaPdnaAuuGUGEecelIO1wx1BpyIfgvfjOh"
					"MBs9M8XL223Fg47xlGsMXdfuY-4jaqVw"
					"."
					"bbd5sTkYwhAIqfHsx8DayA"
					"."
					"0fys_TY_na7f8dwSfXLiYdHaA2DxUjD67ieF7fcVbIR62JhJvGZ4_FNVSiGc_r"
					"aa0HnLQ6s1P2sv3Xzl1p1l_o5wR_RsSzrS8Z-wnI3Jvo0mkpEEnlDmZvDu_k8O"
					"WzJv7eZVEqiWKdyVzFhPpiyQU28GLOpRc2VbVbK4dQKPdNTjPPEmRqcaGeTWZV"
					"yeSUvf5k59yJZxRuSvWFf6KrNtmRdZ8R4mDOjHSrM_s8uwIFcqt4r5GX8TKaI0"
					"zT5CbL5Qlw3sRc7u_hg0yKVOiRytEAEs3vZkcfLkP6nbXdC_PkMdNS-ohP78T2"
					"O6_7uInMGhFeX4ctHG7VelHGiT93JfWDEQi5_V9UN1rhXNrYu-0fVMkZAKX3VW"
					"i7lzA6BP430m"
					"."
					"kvKuFBXHe5mQr4lqgobAUg");

	char * k = "{"
			"\"kty\": \"RSA\","
			"\"kid\": \"[email protected]\","
			"\"use\": \"enc\","
			"\"n\": \"maxhbsmBtdQ3CNrKvprUE6n9lYcregDMLYNeTAWcLj8NnPU9XIYegT"
			"HVHQjxKDSHP2l-F5jS7sppG1wgdAqZyhnWvXhYNvcM7RfgKxqNx_xAHx"
			"6f3yy7s-M9PSNCwPC2lh6UAkR4I00EhV9lrypM9Pi4lBUop9t5fS9W5U"
			"NwaAllhrd-osQGPjIeI1deHTwx-ZTHu3C60Pu_LJIl6hKn9wbwaUmA4c"
			"R5Bd2pgbaY7ASgsjCUbtYJaNIHSoHXprUdJZKUMAzV0WOKPfA6OPI4oy"
			"pBadjvMZ4ZAj3BnXaSYsEZhaueTXvZB4eZOAjIyh2e_VOIKVMsnDrJYA"
			"VotGlvMQ\","
			"\"e\": \"AQAB\","
			"\"d\": \"Kn9tgoHfiTVi8uPu5b9TnwyHwG5dK6RE0uFdlpCGnJN7ZEi963R7wy"
			"bQ1PLAHmpIbNTztfrheoAniRV1NCIqXaW_qS461xiDTp4ntEPnqcKsyO"
			"5jMAji7-CL8vhpYYowNFvIesgMoVaPRYMYT9TW63hNM0aWs7USZ_hLg6"
			"Oe1mY0vHTI3FucjSM86Nff4oIENt43r2fspgEPGRrdE6fpLc9Oaq-qeP"
			"1GFULimrRdndm-P8q8kvN3KHlNAtEgrQAgTTgz80S-3VD0FgWfgnb1PN"
			"miuPUxO8OpI9KDIfu_acc6fg14nsNaJqXe6RESvhGPH2afjHqSy_Fd2v"
			"pzj85bQQ\","
			"\"p\": \"2DwQmZ43FoTnQ8IkUj3BmKRf5Eh2mizZA5xEJ2MinUE3sdTYKSLtaE"
			"oekX9vbBZuWxHdVhM6UnKCJ_2iNk8Z0ayLYHL0_G21aXf9-unynEpUsH"
			"7HHTklLpYAzOOx1ZgVljoxAdWNn3hiEFrjZLZGS7lOH-a3QQlDDQoJOJ"
			"2VFmU\","
			"\"q\": \"te8LY4-W7IyaqH1ExujjMqkTAlTeRbv0VLQnfLY2xINnrWdwiQ93_V"
			"F099aP1ESeLja2nw-6iKIe-qT7mtCPozKfVtUYfz5HrJ_XY2kfexJINb"
			"9lhZHMv5p1skZpeIS-GPHCC6gRlKo1q-idn_qxyusfWv7WAxlSVfQfk8"
			"d6Et0\","
			"\"dp\": \"UfYKcL_or492vVc0PzwLSplbg4L3-Z5wL48mwiswbpzOyIgd2xHTH"
			"QmjJpFAIZ8q-zf9RmgJXkDrFs9rkdxPtAsL1WYdeCT5c125Fkdg317JV"
			"RDo1inX7x2Kdh8ERCreW8_4zXItuTl_KiXZNU5lvMQjWbIw2eTx1lpsf"
			"lo0rYU\","
			"\"dq\": \"iEgcO-QfpepdH8FWd7mUFyrXdnOkXJBCogChY6YKuIHGc_p8Le9Mb"
			"pFKESzEaLlN1Ehf3B6oGBl5Iz_ayUlZj2IoQZ82znoUrpa9fVYNot87A"
			"CfzIG7q9Mv7RiPAderZi03tkVXAdaBau_9vs5rS-7HMtxkVrxSUvJY14"
			"TkXlHE\","
			"\"qi\": \"kC-lzZOqoFaZCr5l0tOVtREKoVqaAYhQiqIRGL-MzS4sCmRkxm5vZ"
			"lXYx6RtE1n_AagjqajlkjieGlxTTThHD8Iga6foGBMaAr5uR1hGQpSc7"
			"Gl7CF1DZkBJMTQN6EshYzZfxW08mIO8M6Rzuh0beL6fG9mkDcIyPrBXx"
			"2bQ_mM\""
			"}";

	apr_jwt_error_t err;
	apr_hash_t *keys = apr_hash_make(pool);
	apr_jwk_t *jwk = NULL;

	TST_ASSERT_ERR("apr_jwk_parse_json", _jwk_parse(pool, k, &jwk, &err) == 0,
			pool, err);
	apr_hash_set(keys, jwk->kid, APR_HASH_KEY_STRING, jwk);

	apr_array_header_t *unpacked = NULL;
	apr_jwt_header_t header;
	memset(&header, 0, sizeof(header));
	TST_ASSERT_ERR("apr_jwt_header_parse",
			apr_jwt_header_parse(pool, s, &unpacked, &header, &err), pool, err);

	char *decrypted = NULL;
	TST_ASSERT_ERR("apr_jwe_decrypt_jwt",
			apr_jwe_decrypt_jwt(pool, &header, unpacked, keys, &decrypted,
					&err), pool, err);

	TST_ASSERT_STR("decrypted", decrypted,
			"You can trust us to stick with you through thick and "
			"thin\342\200\223to the bitter end. And you can trust us to "
			"keep any secret of yours\342\200\223closer than you keep it "
			"yourself. But you cannot trust us to let you face trouble "
			"alone, and go off without a word. We are your friends, Frodo.");

	json_decref(header.value.json);

	return 0;
}
Esempio n. 6
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;
}