示例#1
0
/** Generate the HMAC-SHA1 of a string or attribute
 *
 * Example: "%{hmacsha1:foo bar}" == "Zm9v"
 */
static ssize_t hmac_sha1_xlat(UNUSED void *instance, UNUSED REQUEST *request,
			      char const *fmt, char *out, size_t outlen)
{
	uint8_t const *data, *key;
	char const *p;
	ssize_t data_len, key_len;
	uint8_t digest[SHA1_DIGEST_LENGTH];
	char data_ref[256];

	if (outlen <= (sizeof(digest) * 2)) {
		REDEBUG("Insufficient space to write digest, needed %zu bytes, have %zu bytes",
			(sizeof(digest) * 2) + 1, outlen);
		return -1;
	}

	p = strchr(fmt, ' ');
	if (!p) {
		REDEBUG("HMAC requires exactly two arguments (&data &key)");
		return -1;
	}

	if ((size_t)(p - fmt) >= sizeof(data_ref)) {
		REDEBUG("Insufficient space to store HMAC input data, needed %zu bytes, have %zu bytes",
		        (p - fmt) + 1, sizeof(data_ref));

		return -1;
	}
	strlcpy(data_ref, fmt, (p - fmt) + 1);

	data_len = xlat_fmt_to_ref(&data, request, data_ref);
	if (data_len < 0) return -1;

	while (isspace(*p) && p++);

	key_len = xlat_fmt_to_ref(&key, request, p);
	if (key_len < 0) return -1;

	fr_hmac_sha1(digest, data, data_len, key, key_len);

	return fr_bin2hex(out, digest, sizeof(digest));
}
示例#2
0
static ssize_t evp_md_xlat(UNUSED void *instance, UNUSED REQUEST *request,
			   char const *fmt, char *out, size_t outlen, EVP_MD const *md)
{
	uint8_t digest[EVP_MAX_MD_SIZE];
	unsigned int digestlen, i, len;
	ssize_t inlen;
	uint8_t const *p;

	EVP_MD_CTX *ctx;

	/*
	 *      We need room for at least one octet of output.
	 */
	if (outlen < 3) {
		*out = '\0';
		return 0;
	}

	inlen = xlat_fmt_to_ref(&p, request, fmt);
	if (inlen < 0) {
		return -1;
	}

	ctx = EVP_MD_CTX_create();
	EVP_DigestInit_ex(ctx, md, NULL);
	EVP_DigestUpdate(ctx, p, inlen);
	EVP_DigestFinal_ex(ctx, digest, &digestlen);
	EVP_MD_CTX_destroy(ctx);

	/*
	 *      Each digest octet takes two hex digits, plus one for
	 *      the terminating NUL.
	 */
	len = (outlen / 2) - 1;
	if (len > digestlen) len = digestlen;

	for (i = 0; i < len; i++) {
		snprintf(out + i * 2, 3, "%02x", digest[i]);
	}
	return strlen(out);
}
示例#3
0
/** Calculate the SHA1 hash of a string or attribute.
 *
 * Example: "%{sha1:foo}" == "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
 */
static ssize_t sha1_xlat(UNUSED void *instance, UNUSED REQUEST *request,
			 char const *fmt, char *out, size_t outlen)
{
	uint8_t digest[20];
	ssize_t i, len, inlen;
	uint8_t const *p;
	fr_SHA1_CTX ctx;

	/*
	 *      We need room for at least one octet of output.
	 */
	if (outlen < 3) {
		*out = '\0';
		return 0;
	}

	inlen = xlat_fmt_to_ref(&p, request, fmt);
	if (inlen < 0) {
		return -1;
	}

	fr_sha1_init(&ctx);
	fr_sha1_update(&ctx, p, inlen);
	fr_sha1_final(digest, &ctx);

	/*
	 *      Each digest octet takes two hex digits, plus one for
	 *      the terminating NUL. SHA1 is 160 bits (20 bytes)
	 */
	len = (outlen / 2) - 1;
	if (len > 20) len = 20;

	for (i = 0; i < len; i++) {
		snprintf(out + i * 2, 3, "%02x", digest[i]);
	}

	return strlen(out);
}
示例#4
0
/** Calculate the MD5 hash of a string or attribute.
 *
 * Example: "%{md5:foo}" == "acbd18db4cc2f85cedef654fccc4a4d8"
 */
static ssize_t md5_xlat(UNUSED void *instance, UNUSED REQUEST *request,
                        char const *fmt, char *out, size_t outlen)
{
    uint8_t digest[16];
    ssize_t i, len, inlen;
    uint8_t const *p;
    FR_MD5_CTX ctx;

    /*
     *	We need room for at least one octet of output.
     */
    if (outlen < 3) {
        *out = '\0';
        return 0;
    }

    inlen = xlat_fmt_to_ref(&p, request, fmt);
    if (inlen < 0) {
        return -1;
    }

    fr_MD5Init(&ctx);
    fr_MD5Update(&ctx, p, inlen);
    fr_MD5Final(digest, &ctx);

    /*
     *	Each digest octet takes two hex digits, plus one for
     *	the terminating NUL.
     */
    len = (outlen / 2) - 1;
    if (len > 16) len = 16;

    for (i = 0; i < len; i++) {
        snprintf(out + i * 2, 3, "%02x", digest[i]);
    }

    return strlen(out);
}
示例#5
0
/** Encode string or attribute as base64
 *
 * Example: "%{base64:foo}" == "Zm9v"
 */
static ssize_t base64_xlat(UNUSED void *instance, UNUSED REQUEST *request,
			   char const *fmt, char *out, size_t outlen)
{
	ssize_t inlen;
	uint8_t const *p;

	inlen = xlat_fmt_to_ref(&p, request, fmt);
	if (inlen < 0) {
		return -1;
	}

	/*
	 *  We can accurately calculate the length of the output string
	 *  if it's larger than outlen, the output would be useless so abort.
	 */
	if ((inlen < 0) || ((FR_BASE64_ENC_LENGTH(inlen) + 1) > (ssize_t) outlen)) {
		REDEBUG("xlat failed");
		*out = '\0';
		return -1;
	}

	return fr_base64_encode(out, outlen, p, inlen);
}