add functions to translate between getdns_list and sha256_pin linked list

This commit is contained in:
Daniel Kahn Gillmor 2015-12-21 17:54:43 -05:00 committed by Sara Dickinson
parent 4dbe1813e4
commit b305f073fe
2 changed files with 150 additions and 0 deletions

View File

@ -50,6 +50,7 @@
#include <openssl/bio.h>
#include <openssl/sha.h>
#include <string.h>
#include "context.h"
/* we only support sha256 at the moment. adding support for another
digest is more complex than just adding another entry here. in
@ -212,4 +213,100 @@ getdns_return_t getdns_pubkey_pinset_sanity_check(
return GETDNS_RETURN_GENERIC_ERROR;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
_getdns_get_pubkey_pinset_from_list(const getdns_list *pinset_list,
struct mem_funcs *mf,
sha256_pin_t **pinset_out)
{
getdns_return_t r;
size_t pins, i;
sha256_pin_t *out = NULL, *onext = NULL;
getdns_dict * pin;
getdns_bindata * data = NULL;
if (r = getdns_list_get_length(pinset_list, &pins), r)
return r;
for (i = 0; i < pins; i++)
{
if (r = getdns_list_get_dict(pinset_list, i, &pin), r)
goto fail;
/* does the pin have the right digest type? */
if (r = getdns_dict_get_bindata(pin, "digest", &data), r)
goto fail;
if (data->size != sha256.size ||
memcmp(data->data, sha256.data, sha256.size)) {
r = GETDNS_RETURN_INVALID_PARAMETER;
goto fail;
}
/* if it does, is the value the right length? */
if (r = getdns_dict_get_bindata(pin, "value", &data), r)
goto fail;
if (data->size != SHA256_DIGEST_LENGTH) {
r = GETDNS_RETURN_INVALID_PARAMETER;
goto fail;
}
/* make a new pin */
onext = GETDNS_MALLOC(*mf, sha256_pin_t);
if (onext == NULL) {
r = GETDNS_RETURN_MEMORY_ERROR;
goto fail;
}
onext->next = out;
memcpy(onext->pin, data->data, SHA256_DIGEST_LENGTH);
out = onext;
}
*pinset_out = out;
return GETDNS_RETURN_GOOD;
fail:
while (out) {
onext = out->next;
GETDNS_FREE(*mf, out);
out = onext;
}
return r;
}
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;
}
/* pubkey-pinning.c */

53
src/pubkey-pinning.h Normal file
View File

@ -0,0 +1,53 @@
/**
*
* /brief internal functions for dealing with pubkey pinsets
*
*/
/*
* Copyright (c) 2015 ACLU
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the names of the copyright holders nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PUBKEY_PINNING_H_
#define PUBKEY_PINNING_H_
/* create and populate a pinset linked list from a getdns_list pinset */
getdns_return_t
_getdns_get_pubkey_pinset_from_list(const getdns_list *pinset_list,
struct mem_funcs *mf,
sha256_pin_t **pinset_out);
/* create a getdns_list version of the pinset */
getdns_return_t
_getdns_get_pubkey_pinset_list(getdns_context *ctx,
const sha256_pin_t *pinset_in,
getdns_list **pinset_list);
#endif
/* pubkey-pinning.h */