mirror of https://github.com/getdnsapi/getdns.git
Initial dane support + example (tests_dane)
It is very dependent on dane support in ldns (and will break if it is not there) This needs to be improved, more autoconf detection to see what is possible and not
This commit is contained in:
parent
892d904e5f
commit
d0847f8360
|
@ -71,7 +71,7 @@ EXTENSION_LIBUV_LDFLAGS=@EXTENSION_LIBUV_LDFLAGS@
|
|||
|
||||
GETDNS_OBJ=sync.lo context.lo list.lo dict.lo convert.lo general.lo \
|
||||
hostname.lo service.lo request-internal.lo util-internal.lo \
|
||||
getdns_error.lo rr-dict.lo dnssec.lo const-info.lo
|
||||
getdns_error.lo rr-dict.lo dnssec.lo const-info.lo dane.lo
|
||||
|
||||
.SUFFIXES: .c .o .a .lo .h
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
*
|
||||
* /brief function for DANE
|
||||
*
|
||||
* The getdns_dane_verify function is used to match and validate TLSAs with a
|
||||
* certificate.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, NLnet Labs, Verisign, Inc.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ldns/dane.h>
|
||||
#include "getdns/getdns.h"
|
||||
#include "getdns/getdns_extra.h"
|
||||
#include "config.h"
|
||||
#include "rr-dict.h"
|
||||
|
||||
int
|
||||
getdns_dane_verify(getdns_list *tlsa_rr_dicts, X509 *cert,
|
||||
STACK_OF(X509) *extra_certs, X509_STORE *pkix_validation_store )
|
||||
{
|
||||
getdns_return_t r;
|
||||
ldns_rr_list *tlsas;
|
||||
|
||||
if ((r = priv_getdns_rr_list_from_list(tlsa_rr_dicts, &tlsas)))
|
||||
return r;
|
||||
|
||||
switch (ldns_dane_verify(tlsas, cert,
|
||||
extra_certs, pkix_validation_store)) {
|
||||
case LDNS_STATUS_OK:
|
||||
return GETDNS_RETURN_GOOD;
|
||||
case LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE:
|
||||
return GETDNS_DANE_PKIX_DID_NOT_VALIDATE;
|
||||
case LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH:
|
||||
return GETDNS_DANE_TLSA_DID_NOT_MATCH;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
/* dane.c */
|
32
src/dnssec.c
32
src/dnssec.c
|
@ -328,38 +328,6 @@ priv_getdns_get_validation_chain_sync(getdns_dns_req *dns_req)
|
|||
|
||||
/********************** functions for validate_dnssec *************************/
|
||||
|
||||
static getdns_return_t
|
||||
priv_getdns_rr_list_from_list(struct getdns_list *list, ldns_rr_list **rr_list)
|
||||
{
|
||||
getdns_return_t r;
|
||||
size_t i, l;
|
||||
struct getdns_dict *rr_dict;
|
||||
ldns_rr *rr;
|
||||
|
||||
if ((r = getdns_list_get_length(list, &l)))
|
||||
return r;
|
||||
|
||||
if (! (*rr_list = ldns_rr_list_new()))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
if ((r = getdns_list_get_dict(list, i, &rr_dict)))
|
||||
break;
|
||||
|
||||
if ((r = priv_getdns_create_rr_from_dict(rr_dict, &rr)))
|
||||
break;
|
||||
|
||||
if (! ldns_rr_list_push_rr(*rr_list, rr)) {
|
||||
ldns_rr_free(rr);
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r)
|
||||
ldns_rr_list_deep_free(*rr_list);
|
||||
return r;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
priv_getdns_dnssec_zone_from_list(struct getdns_list *list,
|
||||
ldns_dnssec_zone **zone)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <getdns/getdns.h>
|
||||
#include <sys/time.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -121,6 +122,16 @@ getdns_context_get_extension_data(struct getdns_context* context);
|
|||
getdns_return_t
|
||||
getdns_extension_detach_eventloop(struct getdns_context* context);
|
||||
|
||||
/* dane support */
|
||||
#define GETDNS_DANE_PKIX_DID_NOT_VALIDATE 3000
|
||||
#define GETDNS_DANE_PKIX_DID_NOT_VALIDATE_TEXT "A TLSA matched but PKIX validation failed."
|
||||
#define GETDNS_DANE_TLSA_DID_NOT_MATCH 3001
|
||||
#define GETDNS_DANE_TLSA_DID_NOT_MATCH_TEXT "None of the given TLSAs matched"
|
||||
|
||||
int /* actually extended getdns_return_t */
|
||||
getdns_dane_verify(getdns_list *tlsas, X509 *cert,
|
||||
STACK_OF(X509) *extra_certs, X509_STORE *pkix_validation_store );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1234,6 +1234,42 @@ priv_getdns_create_rr_from_dict(struct getdns_dict *rr_dict, ldns_rr **rr)
|
|||
return r;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
priv_getdns_rr_list_from_list(struct getdns_list *list, ldns_rr_list **rr_list)
|
||||
{
|
||||
getdns_return_t r;
|
||||
size_t i, l;
|
||||
struct getdns_dict *rr_dict;
|
||||
ldns_rr *rr;
|
||||
|
||||
if (list == NULL) {
|
||||
l = 0;
|
||||
r = GETDNS_RETURN_GOOD;
|
||||
|
||||
} else if ((r = getdns_list_get_length(list, &l)))
|
||||
return r;
|
||||
|
||||
if (! (*rr_list = ldns_rr_list_new()))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
if ((r = getdns_list_get_dict(list, i, &rr_dict)))
|
||||
break;
|
||||
|
||||
if ((r = priv_getdns_create_rr_from_dict(rr_dict, &rr)))
|
||||
break;
|
||||
|
||||
if (! ldns_rr_list_push_rr(*rr_list, rr)) {
|
||||
ldns_rr_free(rr);
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r)
|
||||
ldns_rr_list_deep_free(*rr_list);
|
||||
return r;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
priv_getdns_get_opt_dict(struct getdns_context* context,
|
||||
struct getdns_dict** record_dict, uint8_t* record_start,
|
||||
|
|
|
@ -44,6 +44,9 @@ getdns_return_t priv_getdns_create_reply_question_dict(
|
|||
getdns_return_t priv_getdns_create_rr_from_dict(
|
||||
struct getdns_dict *rr_dict, ldns_rr **rr);
|
||||
|
||||
getdns_return_t priv_getdns_rr_list_from_list(
|
||||
struct getdns_list *list, ldns_rr_list **rr_list);
|
||||
|
||||
const char *priv_getdns_rr_type_name(int rr_type);
|
||||
|
||||
getdns_return_t priv_getdns_append_opt_rr(
|
||||
|
|
|
@ -58,7 +58,7 @@ CC=@CC@
|
|||
CFLAGS=@CFLAGS@ -Wall -I$(srcdir)/ -I$(srcdir)/../ -I/usr/local/include -std=c99 $(cflags)
|
||||
LDFLAGS=@LDFLAGS@ -L. -L.. -L$(srcdir)/../ -L/usr/local/lib
|
||||
LDLIBS=-lgetdns @LIBS@ -lcheck
|
||||
PROGRAMS=tests_dict tests_list tests_stub_async tests_stub_sync check_getdns tests_dnssec $(CHECK_EV_PROG) $(CHECK_EVENT_PROG) $(CHECK_UV_PROG)
|
||||
PROGRAMS=tests_dict tests_list tests_stub_async tests_stub_sync check_getdns tests_dnssec tests_dane $(CHECK_EV_PROG) $(CHECK_EVENT_PROG) $(CHECK_UV_PROG)
|
||||
|
||||
.SUFFIXES: .c .o .a .lo .h
|
||||
|
||||
|
@ -99,6 +99,8 @@ check_getdns_ev: check_getdns.o check_getdns_common.o check_getdns_context_set_t
|
|||
tests_dnssec: tests_dnssec.o testmessages.o
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_dnssec.o testmessages.o
|
||||
|
||||
tests_dane: tests_dane.o testmessages.o
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_dane.o testmessages.o
|
||||
|
||||
test: all
|
||||
./check_getdns
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
/**
|
||||
* \file
|
||||
* unit tests for getdns_dict helper routines, these should be used to
|
||||
* perform regression tests, output must be unchanged from canonical output
|
||||
* stored with the sources
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, NLNet Labs, Verisign, Inc.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <getdns/getdns.h>
|
||||
#include <getdns/getdns_extra.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
getdns_return_t r;
|
||||
|
||||
const char *hostname;
|
||||
int port = 443;
|
||||
char danename[1024];
|
||||
|
||||
getdns_context *context;
|
||||
getdns_dict *response;
|
||||
getdns_dict *extensions;
|
||||
getdns_list *replies_tree;
|
||||
uint32_t status;
|
||||
getdns_dict *reply;
|
||||
getdns_list *tlsas;
|
||||
size_t ntlsas;
|
||||
getdns_dict *response2;
|
||||
getdns_list *addresses;
|
||||
size_t naddresses, i;
|
||||
SSL_CTX *ctx;
|
||||
getdns_dict *address;
|
||||
|
||||
getdns_bindata *address_type;
|
||||
getdns_bindata *address_data;
|
||||
|
||||
struct sockaddr_storage sas;
|
||||
struct sockaddr_in *sa4 = (struct sockaddr_in *)&sas;
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&sas;
|
||||
size_t sa_len;
|
||||
|
||||
char *address_str;
|
||||
int sock;
|
||||
SSL *ssl;
|
||||
int ssl_status;
|
||||
|
||||
X509 *cert;
|
||||
STACK_OF(X509) *extra_certs;
|
||||
|
||||
/* Number of successfully validated addresses */
|
||||
int nsuccess = 0;
|
||||
|
||||
/*
|
||||
* Get hostname and optional port from commandline arguments.
|
||||
*/
|
||||
if (argc == 3)
|
||||
port = atoi(argv[2]);
|
||||
|
||||
else if (argc != 2) {
|
||||
|
||||
printf("usage: %s <hostname> [ <port> ]\n", progname);
|
||||
printf("\t<port> defaults to 443\n");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
hostname = argv[1];
|
||||
|
||||
/*
|
||||
* Setup getdns stub resolution
|
||||
*/
|
||||
if ((r = getdns_context_create(&context, 1)))
|
||||
return r;
|
||||
|
||||
if ((r = getdns_context_set_resolution_type(
|
||||
context, GETDNS_RESOLUTION_STUB)))
|
||||
goto done_destroy_context;
|
||||
|
||||
if (! (extensions = getdns_dict_create())) {
|
||||
r = GETDNS_RETURN_MEMORY_ERROR;
|
||||
goto done_destroy_context;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup TLSA's (but only when they are secure (i.e. DNSSEC signed))
|
||||
*/
|
||||
if ((r = getdns_dict_set_int(
|
||||
extensions, "dnssec_return_only_secure", GETDNS_EXTENSION_TRUE)))
|
||||
goto done_destroy_extensions;
|
||||
|
||||
/* construct the dane name */
|
||||
(void) snprintf(danename, 1024, "_%d._tcp.%s", port, hostname);
|
||||
|
||||
/* actual lookup */
|
||||
if ((r = getdns_general_sync(context,
|
||||
danename, GETDNS_RRTYPE_TLSA, extensions, &response)))
|
||||
goto done_destroy_extensions;
|
||||
|
||||
/* Did we get anything? Securely? */
|
||||
if ((r = getdns_dict_get_int(response, "status", &status)))
|
||||
goto done_destroy_response;
|
||||
|
||||
if (status == GETDNS_RESPSTATUS_NO_SECURE_ANSWERS) {
|
||||
printf("No secure TLSA RR's for %s were found.\n", danename);
|
||||
printf("PKIX validation without dane will be performed.\n");
|
||||
tlsas = NULL;
|
||||
ntlsas = 0;
|
||||
|
||||
} else {
|
||||
/* descend into response dict to get to the tlsas */
|
||||
if ((r = getdns_dict_get_list(
|
||||
response, "replies_tree", &replies_tree)))
|
||||
goto done_destroy_response;
|
||||
|
||||
if ((r = getdns_list_get_dict(replies_tree, 0, &reply)))
|
||||
goto done_destroy_response;
|
||||
|
||||
if ((r = getdns_dict_get_list(reply, "answer", &tlsas)))
|
||||
goto done_destroy_response;
|
||||
|
||||
if ((r = getdns_list_get_length(tlsas, &ntlsas)))
|
||||
goto done_destroy_response;
|
||||
|
||||
if (ntlsas == 0) {
|
||||
printf("No TLSA RR's for %s were found.\n", danename);
|
||||
printf("PKIX validation "
|
||||
"without dane will be performed.\n");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Lookup addresses for the hostname (don't have to be secure).
|
||||
*/
|
||||
if ((r = getdns_address_sync(context, hostname, NULL, &response2)))
|
||||
goto done_destroy_response;
|
||||
|
||||
/* get the addresses from the response dict */
|
||||
if ((r = getdns_dict_get_list(response2, "just_address_answers",
|
||||
&addresses)))
|
||||
goto done_destroy_response2;
|
||||
|
||||
/* exit when there are none */
|
||||
if ((r = getdns_list_get_length(addresses, &naddresses)))
|
||||
goto done_destroy_response2;
|
||||
if (naddresses <= 0) {
|
||||
printf("%s did not have any addresses to connect to\n", hostname);
|
||||
goto done_destroy_response2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup OpenSSL context
|
||||
*/
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if (! ctx) {
|
||||
fprintf(stderr, "could not SSL_CTX_new\n");
|
||||
r = EXIT_FAILURE;
|
||||
goto done_destroy_response2;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each address SSL connect and get and verify the certificate
|
||||
*/
|
||||
for (i = 0; i < naddresses && r == GETDNS_RETURN_GOOD; i++) {
|
||||
|
||||
if ((r = getdns_list_get_dict(addresses, i, &address)))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Create a sockaddr_in from <address> <port>
|
||||
*/
|
||||
if ((r = getdns_dict_get_bindata(
|
||||
address, "address_type", &address_type)))
|
||||
return r;
|
||||
|
||||
if ((r = getdns_dict_get_bindata(
|
||||
address, "address_data", &address_data)))
|
||||
return r;
|
||||
|
||||
if (strncmp((const char *)address_type->data, "IPv4", 4) == 0) {
|
||||
|
||||
sas.ss_family = AF_INET;
|
||||
sa4->sin_port = htons(port);
|
||||
memcpy(&(sa4->sin_addr),address_data->data,
|
||||
address_data->size);
|
||||
sa_len = sizeof(struct sockaddr_in);
|
||||
|
||||
} else if (strncmp((const char *)address_type->data, "IPv6", 4) == 0) {
|
||||
|
||||
sas.ss_family = AF_INET6;
|
||||
sa6->sin6_port = htons(port);
|
||||
memcpy(&(sa6->sin6_addr), address_data->data,
|
||||
address_data->size);
|
||||
sa_len = sizeof(struct sockaddr_in6);
|
||||
|
||||
} else {
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open and tcp-connect a socket with this sockaddr_in
|
||||
*/
|
||||
sock = socket(sas.ss_family, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sock == -1) {
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* display connection details */
|
||||
address_str = getdns_display_ip_address(address_data);
|
||||
printf("Connecting to %s%s%s:%d... ",
|
||||
(sas.ss_family == AF_INET6 ? "[" : ""), address_str,
|
||||
(sas.ss_family == AF_INET6 ? "]" : ""), port);
|
||||
free(address_str);
|
||||
|
||||
/* and connect */
|
||||
if (connect(sock, (struct sockaddr *)&sas, sa_len) == -1) {
|
||||
printf("failed\n");
|
||||
close(sock);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create ssl
|
||||
*/
|
||||
ssl = SSL_new(ctx);
|
||||
if (! ssl) {
|
||||
printf("failed setting up ssl (creating)\n");
|
||||
close(sock);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Associate ssl with the hostname
|
||||
*/
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||
(void) SSL_set_tlsext_host_name(ssl, hostname);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Associate ssl with the connected socket
|
||||
*/
|
||||
SSL_set_connect_state(ssl);
|
||||
(void) SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
if (! SSL_set_fd(ssl, sock)) {
|
||||
printf("failed setting up ssl (associating socket)\n");
|
||||
SSL_free(ssl);
|
||||
close(sock);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shake hands and get the certificates
|
||||
*/
|
||||
for (;;) {
|
||||
ERR_clear_error();
|
||||
if ((ssl_status = SSL_do_handshake(ssl)) == 1) {
|
||||
break;
|
||||
}
|
||||
ssl_status = SSL_get_error(ssl, ssl_status);
|
||||
if (ssl_status != SSL_ERROR_WANT_READ &&
|
||||
ssl_status != SSL_ERROR_WANT_WRITE) {
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r == GETDNS_RETURN_GENERIC_ERROR) {
|
||||
r = GETDNS_RETURN_GOOD;
|
||||
printf("failed setting up ssl (handshaking)\n");
|
||||
SSL_free(ssl);
|
||||
close(sock);
|
||||
continue;
|
||||
}
|
||||
|
||||
cert = SSL_get_peer_certificate(ssl);
|
||||
extra_certs = SSL_get_peer_cert_chain(ssl);
|
||||
|
||||
/*
|
||||
* Dane validate the certificate
|
||||
*/
|
||||
switch (getdns_dane_verify(tlsas, cert, extra_certs, NULL)) {
|
||||
case GETDNS_RETURN_GOOD:
|
||||
printf("dane-validated successfully.\n");
|
||||
nsuccess++;
|
||||
break;
|
||||
|
||||
case GETDNS_DANE_PKIX_DID_NOT_VALIDATE:
|
||||
if (ntlsas) printf("A TLSA matched, but ");
|
||||
printf("PKIX validation failed\n");
|
||||
break;
|
||||
|
||||
case GETDNS_DANE_TLSA_DID_NOT_MATCH:
|
||||
printf("No matching TLSA found\n");
|
||||
break;
|
||||
default:
|
||||
printf("An error occurred when verifying TLSA's\n");
|
||||
break;
|
||||
}
|
||||
while (SSL_shutdown(ssl) == 0);
|
||||
SSL_free(ssl);
|
||||
|
||||
} /* for (i = 0; i < naddresses && r == GETDNS_RETURN_GOOD; i++) */
|
||||
|
||||
/* Clean up */
|
||||
SSL_CTX_free(ctx);
|
||||
|
||||
done_destroy_response2:
|
||||
getdns_dict_destroy(response2);
|
||||
|
||||
done_destroy_response:
|
||||
getdns_dict_destroy(response);
|
||||
|
||||
done_destroy_extensions:
|
||||
getdns_dict_destroy(extensions);
|
||||
|
||||
done_destroy_context:
|
||||
getdns_context_destroy(context);
|
||||
|
||||
return r ? r : (naddresses == nsuccess ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* tests_dane.c */
|
Loading…
Reference in New Issue