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/bio.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <string.h> #include <string.h>
#include "context.h"
/* we only support sha256 at the moment. adding support for another /* we only support sha256 at the moment. adding support for another
digest is more complex than just adding another entry here. in 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_GENERIC_ERROR;
return GETDNS_RETURN_GOOD; 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 */ /* 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 */