mirror of https://github.com/getdnsapi/getdns.git
add getdns_pubkey_pinset_sanity_check()
This commit is contained in:
parent
91f04ecd5e
commit
5e64f1262b
|
@ -378,6 +378,26 @@ getdns_dict* getdns_pubkey_pin_create_from_string(
|
||||||
getdns_context* context,
|
getdns_context* context,
|
||||||
const char* str);
|
const char* str);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether a given pinset is reasonable, including:
|
||||||
|
*
|
||||||
|
* is it well-formed?
|
||||||
|
* are there at least two pins?
|
||||||
|
* are the digests used sane?
|
||||||
|
*
|
||||||
|
* @param pinset the set of public key pins to check for sanity. This
|
||||||
|
* should be a list of dicts.
|
||||||
|
* @return errorlist if not NULL, a list of human-readable strings is
|
||||||
|
* appended to errorlist.
|
||||||
|
* @return GETDNS_RETURN_GOOD if the pinset passes the sanity check.
|
||||||
|
*/
|
||||||
|
getdns_return_t getdns_pubkey_pinset_sanity_check(
|
||||||
|
const getdns_list* pinset,
|
||||||
|
getdns_list* errorlist);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* WARNING! Function getdns_strerror is not in the API specification and
|
/* WARNING! Function getdns_strerror is not in the API specification and
|
||||||
* is likely to be removed from future versions of our implementation, to be
|
* is likely to be removed from future versions of our implementation, to be
|
||||||
* replaced by getdns_get_errorstr_by_id or something similar.
|
* replaced by getdns_get_errorstr_by_id or something similar.
|
||||||
|
|
|
@ -115,6 +115,7 @@ getdns_pretty_snprint_list
|
||||||
getdns_print_json_dict
|
getdns_print_json_dict
|
||||||
getdns_print_json_list
|
getdns_print_json_list
|
||||||
getdns_pubkey_pin_create_from_string
|
getdns_pubkey_pin_create_from_string
|
||||||
|
getdns_pubkey_pinset_sanity_check
|
||||||
getdns_root_trust_anchor
|
getdns_root_trust_anchor
|
||||||
getdns_rr_dict2str
|
getdns_rr_dict2str
|
||||||
getdns_rr_dict2str_buf
|
getdns_rr_dict2str_buf
|
||||||
|
|
|
@ -137,4 +137,79 @@ getdns_dict* getdns_pubkey_pin_create_from_string(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Test whether a given pinset is reasonable, including:
|
||||||
|
|
||||||
|
* is it well-formed?
|
||||||
|
* are there at least two pins?
|
||||||
|
* are the digests used sane?
|
||||||
|
|
||||||
|
if errorlist is NULL, the sanity check just returns success or
|
||||||
|
failure.
|
||||||
|
|
||||||
|
if errorlist is not NULL, we append human-readable strings to
|
||||||
|
report the errors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PKP_SC_ERR(e) { \
|
||||||
|
err.size = sizeof(e); \
|
||||||
|
err.data = (uint8_t*)e; \
|
||||||
|
if (errorlist) \
|
||||||
|
getdns_list_set_bindata(errorlist, \
|
||||||
|
preverrs + errorcount, &err); \
|
||||||
|
errorcount++; \
|
||||||
|
}
|
||||||
|
#define PKP_SC_HARDERR(e, val) { \
|
||||||
|
PKP_SC_ERR(e); return val; \
|
||||||
|
}
|
||||||
|
getdns_return_t getdns_pubkey_pinset_sanity_check(
|
||||||
|
const getdns_list* pinset,
|
||||||
|
getdns_list* errorlist)
|
||||||
|
{
|
||||||
|
size_t errorcount = 0, preverrs = 0, pins = 0, i;
|
||||||
|
getdns_bindata err;
|
||||||
|
getdns_dict * pin;
|
||||||
|
getdns_bindata * data;
|
||||||
|
|
||||||
|
if (errorlist)
|
||||||
|
if (getdns_list_get_length(errorlist, &preverrs))
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (getdns_list_get_length(pinset, &pins))
|
||||||
|
PKP_SC_HARDERR("Can't get length of pinset",
|
||||||
|
GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
if (pins < 2)
|
||||||
|
PKP_SC_ERR("This pinset has fewer than 2 pins");
|
||||||
|
for (i = 0; i < pins; i++)
|
||||||
|
{
|
||||||
|
/* is it a dict? */
|
||||||
|
if (getdns_list_get_dict(pinset, i, &pin)) {
|
||||||
|
PKP_SC_ERR("Could not retrieve a pin");
|
||||||
|
} else {
|
||||||
|
/* does the pin have the right digest type? */
|
||||||
|
if (getdns_dict_get_bindata(pin, "digest", &data)) {
|
||||||
|
PKP_SC_ERR("Pin has no 'digest' entry");
|
||||||
|
} else {
|
||||||
|
if (data->size != sha256.size ||
|
||||||
|
memcmp(data->data, sha256.data, sha256.size))
|
||||||
|
PKP_SC_ERR("Pin has 'digest' other than sha256");
|
||||||
|
}
|
||||||
|
/* if it does, is the value the right length? */
|
||||||
|
if (getdns_dict_get_bindata(pin, "value", &data)) {
|
||||||
|
PKP_SC_ERR("Pin has no 'value' entry");
|
||||||
|
} else {
|
||||||
|
if (data->size != SHA256_DIGEST_LENGTH)
|
||||||
|
PKP_SC_ERR("Pin has the wrong size 'value' (should be 32 octets for sha256)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* should we choke if it has some other key? for
|
||||||
|
* extensibility, we will not treat this as an
|
||||||
|
* error.*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorcount > 0)
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
/* pubkey-pinning.c */
|
/* pubkey-pinning.c */
|
||||||
|
|
Loading…
Reference in New Issue