示例#1
0
/* convert an HPKP-style pin description to an appropriate getdns data
   structure.  An example string is: (with the quotes, without any
   leading or trailing whitespace):

      pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="

   getdns_build_pin_from_string returns a dict created from ctx, or
   NULL if the string did not match.  If ctx is NULL, the dict is
   created via getdns_dict_create().

   It is the caller's responsibility to call getdns_dict_destroy when
   it is no longer needed.
 */
getdns_dict* getdns_pubkey_pin_create_from_string(
	getdns_context* context,
	const char* str)
{
	BIO *bio = NULL;
	int i;
	uint8_t buf[SHA256_DIGEST_LENGTH];
	char inbuf[B64_ENCODED_SHA256_LENGTH + 1];
	getdns_bindata value = { .size = SHA256_DIGEST_LENGTH, .data = buf };
	getdns_dict* out = NULL;
	
	/* we only do sha256 right now, make sure this is well-formed */
	if (strncmp(PIN_PREFIX, str, PIN_PREFIX_LENGTH))
		return NULL;
	for (i = PIN_PREFIX_LENGTH; i < PIN_PREFIX_LENGTH + B64_ENCODED_SHA256_LENGTH - 1; i++)
		if (!((str[i] >= 'a' && str[i] <= 'z') ||
		      (str[i] >= 'A' && str[i] <= 'Z') ||
		      (str[i] >= '0' && str[i] <= '9') ||
		      (str[i] == '+') || (str[i] == '/')))
			return NULL;
	if (str[i++] != '=')
		return NULL;
	if (str[i++] != '"')
		return NULL;
	if (str[i++] != '\0')
		return NULL;

	/* openssl needs a trailing newline to base64 decode */
	memcpy(inbuf, str + PIN_PREFIX_LENGTH, B64_ENCODED_SHA256_LENGTH);
	inbuf[B64_ENCODED_SHA256_LENGTH] = '\n';
	
	bio = BIO_push(BIO_new(BIO_f_base64()),
		       BIO_new_mem_buf(inbuf, sizeof(inbuf)));
	if (BIO_read(bio, buf, sizeof(buf)) != sizeof(buf))
		goto fail;
	
	if (context)
		out = getdns_dict_create_with_context(context);
	else
		out = getdns_dict_create();
	if (out == NULL)
		goto fail;
	if (getdns_dict_set_bindata(out, "digest", &sha256))
		goto fail;
	if (getdns_dict_set_bindata(out, "value", &value))
		goto fail;
	return out;

 fail:
	BIO_free_all(bio);
	getdns_dict_destroy(out);
	return NULL;
}
示例#2
0
getdns_dict *
ipaddr_dict(getdns_context *context, char *ipstr)
{
	getdns_dict *r = getdns_dict_create_with_context(context);
	char *s = strchr(ipstr, '%'), *scope_id_str = "";
	char *p = strchr(ipstr, '@'), *portstr = "";
	char *t = strchr(ipstr, '#'), *tls_portstr = "";
	uint8_t buf[sizeof(struct in6_addr)];
	getdns_bindata addr;

	addr.data = buf;

	if (!r) return NULL;
	if (s) {
		*s = 0;
		scope_id_str = s + 1;
	}
	if (p) {
		*p = 0;
		portstr = p + 1;
	}
	if (t) {
		*t = 0;
		tls_portstr = t + 1;
	}
	if (strchr(ipstr, ':')) {
		getdns_dict_util_set_string(r, "address_type", "IPv6");
		addr.size = 16;
		if (inet_pton(AF_INET6, ipstr, buf) <= 0) {
			getdns_dict_destroy(r);
			return NULL;
		}
	} else {
		getdns_dict_util_set_string(r, "address_type", "IPv4");
		addr.size = 4;
		if (inet_pton(AF_INET, ipstr, buf) <= 0) {
			getdns_dict_destroy(r);
			return NULL;
		}
	}
	getdns_dict_set_bindata(r, "address_data", &addr);
	if (*portstr)
		getdns_dict_set_int(r, "port", (int32_t)atoi(portstr));
	if (*tls_portstr)
		getdns_dict_set_int(r, "tls_port", (int32_t)atoi(tls_portstr));
	if (*scope_id_str)
		getdns_dict_util_set_string(r, "scope_id", scope_id_str);

	return r;
}
示例#3
0
/* convert an HPKP-style pin description to an appropriate getdns data
   structure.  An example string is: (with the quotes, without any
   leading or trailing whitespace):

      pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="

   getdns_build_pin_from_string returns a dict created from ctx, or
   NULL if the string did not match.  If ctx is NULL, the dict is
   created via getdns_dict_create().

   It is the caller's responsibility to call getdns_dict_destroy when
   it is no longer needed.
 */
getdns_dict *getdns_pubkey_pin_create_from_string(
   const getdns_context *context, const char *str)
{
	size_t i;
	uint8_t buf[SHA256_DIGEST_LENGTH];
	getdns_bindata value = { .size = SHA256_DIGEST_LENGTH, .data = buf };
	getdns_dict *out = NULL;
	
	/* we only do sha256 right now, make sure this is well-formed */
	if (!str || strncmp(PIN_PREFIX, str, PIN_PREFIX_LENGTH))
		return NULL;
	for (i = PIN_PREFIX_LENGTH; i < PIN_PREFIX_LENGTH + B64_ENCODED_SHA256_LENGTH - 1; i++)
		if (!((str[i] >= 'a' && str[i] <= 'z') ||
		      (str[i] >= 'A' && str[i] <= 'Z') ||
		      (str[i] >= '0' && str[i] <= '9') ||
		      (str[i] == '+') || (str[i] == '/')))
			return NULL;
	if (str[i++] != '=')
		return NULL;
	if (str[i++] != '"')
		return NULL;
	if (str[i++] != '\0')
		return NULL;

	if (_getdns_decode_base64(str + PIN_PREFIX_LENGTH, buf, sizeof(buf)) != GETDNS_RETURN_GOOD)
	    goto fail;
	    
	if (context)
		out = getdns_dict_create_with_context(context);
	else
		out = getdns_dict_create();
	if (out == NULL)
		goto fail;
	if (getdns_dict_set_bindata(out, "digest", &sha256))
		goto fail;
	if (getdns_dict_set_bindata(out, "value", &value))
		goto fail;
	return out;

 fail:
	getdns_dict_destroy(out);
	return NULL;
}
示例#4
0
getdns_return_t
_getdns_get_pubkey_pinset_list(getdns_context *ctx,
			       const sha256_pin_t *pinset_in,
			       getdns_list **pinset_list)
{
	getdns_list *out = getdns_list_create_with_context(ctx);
	getdns_return_t r;
	uint8_t buf[SHA256_DIGEST_LENGTH];
	getdns_bindata value = { .size = SHA256_DIGEST_LENGTH, .data = buf };
	getdns_dict *pin = NULL;
	size_t idx = 0;

	if (out == NULL)
		return GETDNS_RETURN_MEMORY_ERROR;
	while (pinset_in) {
		pin = getdns_dict_create_with_context(ctx);
		if (pin == NULL) {
			r = GETDNS_RETURN_MEMORY_ERROR;
			goto fail;
		}
		if (r = getdns_dict_set_bindata(pin, "digest", &sha256), r)
			goto fail;
		memcpy(buf, pinset_in->pin, sizeof(buf));
		if (r = getdns_dict_set_bindata(pin, "value", &value), r)
			goto fail;
		if (r = getdns_list_set_dict(out, idx++, pin), r)
			goto fail;
		getdns_dict_destroy(pin);
		pin = NULL;
		pinset_in = pinset_in->next;
	}

	*pinset_list = out;
	return GETDNS_RETURN_GOOD;
 fail:
	getdns_dict_destroy(pin);
	getdns_list_destroy(out);
	return r;
}