00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <ldns/config.h>
00011
00012 #include <ldns/ldns.h>
00013 #include <ldns/dane.h>
00014
00015 #include <unistd.h>
00016 #include <stdlib.h>
00017 #include <sys/types.h>
00018 #include <sys/socket.h>
00019 #include <netdb.h>
00020
00021 #ifdef HAVE_SSL
00022 #include <openssl/ssl.h>
00023 #include <openssl/err.h>
00024 #include <openssl/x509v3.h>
00025 #endif
00026
00027 ldns_status
00028 ldns_dane_create_tlsa_owner(ldns_rdf** tlsa_owner, const ldns_rdf* name,
00029 uint16_t port, ldns_dane_transport transport)
00030 {
00031 char buf[LDNS_MAX_DOMAINLEN];
00032 size_t s;
00033
00034 assert(tlsa_owner != NULL);
00035 assert(name != NULL);
00036 assert(ldns_rdf_get_type(name) == LDNS_RDF_TYPE_DNAME);
00037
00038 s = (size_t)snprintf(buf, LDNS_MAX_DOMAINLEN, "X_%d", (int)port);
00039 buf[0] = (char)(s - 1);
00040
00041 switch(transport) {
00042 case LDNS_DANE_TRANSPORT_TCP:
00043 s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_tcp");
00044 break;
00045
00046 case LDNS_DANE_TRANSPORT_UDP:
00047 s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_udp");
00048 break;
00049
00050 case LDNS_DANE_TRANSPORT_SCTP:
00051 s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\005_sctp");
00052 break;
00053
00054 default:
00055 return LDNS_STATUS_DANE_UNKNOWN_TRANSPORT;
00056 }
00057 if (s + ldns_rdf_size(name) > LDNS_MAX_DOMAINLEN) {
00058 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00059 }
00060 memcpy(buf + s, ldns_rdf_data(name), ldns_rdf_size(name));
00061 *tlsa_owner = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
00062 s + ldns_rdf_size(name), buf);
00063 if (*tlsa_owner == NULL) {
00064 return LDNS_STATUS_MEM_ERR;
00065 }
00066 return LDNS_STATUS_OK;
00067 }
00068
00069
00070 #ifdef HAVE_SSL
00071 ldns_status
00072 ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
00073 ldns_tlsa_selector selector,
00074 ldns_tlsa_matching_type matching_type)
00075 {
00076 unsigned char* buf = NULL;
00077 size_t len;
00078
00079 X509_PUBKEY* xpubkey;
00080 EVP_PKEY* epubkey;
00081
00082 unsigned char* digest;
00083
00084 assert(rdf != NULL);
00085 assert(cert != NULL);
00086
00087 switch(selector) {
00088 case LDNS_TLSA_SELECTOR_FULL_CERTIFICATE:
00089
00090 len = (size_t)i2d_X509(cert, &buf);
00091 break;
00092
00093 case LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO:
00094
00095 #ifndef S_SPLINT_S
00096 xpubkey = X509_get_X509_PUBKEY(cert);
00097 #endif
00098 if (! xpubkey) {
00099 return LDNS_STATUS_SSL_ERR;
00100 }
00101 epubkey = X509_PUBKEY_get(xpubkey);
00102 if (! epubkey) {
00103 return LDNS_STATUS_SSL_ERR;
00104 }
00105 len = (size_t)i2d_PUBKEY(epubkey, &buf);
00106 break;
00107
00108 default:
00109 return LDNS_STATUS_DANE_UNKNOWN_SELECTOR;
00110 }
00111
00112 switch(matching_type) {
00113 case LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED:
00114
00115 *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, len, buf);
00116
00117 return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
00118 break;
00119
00120 case LDNS_TLSA_MATCHING_TYPE_SHA256:
00121
00122 digest = LDNS_XMALLOC(unsigned char, SHA256_DIGEST_LENGTH);
00123 if (digest == NULL) {
00124 LDNS_FREE(buf);
00125 return LDNS_STATUS_MEM_ERR;
00126 }
00127 (void) ldns_sha256(buf, (unsigned int)len, digest);
00128 *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA256_DIGEST_LENGTH,
00129 digest);
00130 LDNS_FREE(buf);
00131
00132 return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
00133 break;
00134
00135 case LDNS_TLSA_MATCHING_TYPE_SHA512:
00136
00137 digest = LDNS_XMALLOC(unsigned char, SHA512_DIGEST_LENGTH);
00138 if (digest == NULL) {
00139 LDNS_FREE(buf);
00140 return LDNS_STATUS_MEM_ERR;
00141 }
00142 (void) ldns_sha512(buf, (unsigned int)len, digest);
00143 *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA512_DIGEST_LENGTH,
00144 digest);
00145 LDNS_FREE(buf);
00146
00147 return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
00148 break;
00149
00150 default:
00151 LDNS_FREE(buf);
00152 return LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE;
00153 }
00154 }
00155
00156
00157
00158
00159
00160 static ldns_status
00161 ldns_dane_pkix_validate(X509* cert, STACK_OF(X509)* extra_certs,
00162 X509_STORE* store)
00163 {
00164 X509_STORE_CTX* vrfy_ctx;
00165 ldns_status s;
00166
00167 if (! store) {
00168 return LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
00169 }
00170 vrfy_ctx = X509_STORE_CTX_new();
00171 if (! vrfy_ctx) {
00172
00173 return LDNS_STATUS_SSL_ERR;
00174
00175 } else if (X509_STORE_CTX_init(vrfy_ctx, store,
00176 cert, extra_certs) != 1) {
00177 s = LDNS_STATUS_SSL_ERR;
00178
00179 } else if (X509_verify_cert(vrfy_ctx) == 1) {
00180
00181 s = LDNS_STATUS_OK;
00182
00183 } else {
00184 s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
00185 }
00186 X509_STORE_CTX_free(vrfy_ctx);
00187 return s;
00188 }
00189
00190
00191
00192
00193
00194 static ldns_status
00195 ldns_dane_pkix_validate_and_get_chain(STACK_OF(X509)** chain, X509* cert,
00196 STACK_OF(X509)* extra_certs, X509_STORE* store)
00197 {
00198 ldns_status s;
00199 X509_STORE* empty_store = NULL;
00200 X509_STORE_CTX* vrfy_ctx;
00201
00202 assert(chain != NULL);
00203
00204 if (! store) {
00205 store = empty_store = X509_STORE_new();
00206 }
00207 s = LDNS_STATUS_SSL_ERR;
00208 vrfy_ctx = X509_STORE_CTX_new();
00209 if (! vrfy_ctx) {
00210
00211 goto exit_free_empty_store;
00212
00213 } else if (X509_STORE_CTX_init(vrfy_ctx, store,
00214 cert, extra_certs) != 1) {
00215 goto exit_free_vrfy_ctx;
00216
00217 } else if (X509_verify_cert(vrfy_ctx) == 1) {
00218
00219 s = LDNS_STATUS_OK;
00220
00221 } else {
00222 s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
00223 }
00224 *chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
00225 if (! *chain) {
00226 s = LDNS_STATUS_SSL_ERR;
00227 }
00228
00229 exit_free_vrfy_ctx:
00230 X509_STORE_CTX_free(vrfy_ctx);
00231
00232 exit_free_empty_store:
00233 if (empty_store) {
00234 X509_STORE_free(empty_store);
00235 }
00236 return s;
00237 }
00238
00239
00240
00241
00242 static ldns_status
00243 ldns_dane_pkix_get_chain(STACK_OF(X509)** chain,
00244 X509* cert, STACK_OF(X509)* extra_certs)
00245 {
00246 ldns_status s;
00247 X509_STORE* empty_store = NULL;
00248 X509_STORE_CTX* vrfy_ctx;
00249
00250 assert(chain != NULL);
00251
00252 empty_store = X509_STORE_new();
00253 s = LDNS_STATUS_SSL_ERR;
00254 vrfy_ctx = X509_STORE_CTX_new();
00255 if (! vrfy_ctx) {
00256
00257 goto exit_free_empty_store;
00258
00259 } else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
00260 cert, extra_certs) != 1) {
00261 goto exit_free_vrfy_ctx;
00262 }
00263 (void) X509_verify_cert(vrfy_ctx);
00264 *chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
00265 if (! *chain) {
00266 s = LDNS_STATUS_SSL_ERR;
00267 } else {
00268 s = LDNS_STATUS_OK;
00269 }
00270 exit_free_vrfy_ctx:
00271 X509_STORE_CTX_free(vrfy_ctx);
00272
00273 exit_free_empty_store:
00274 X509_STORE_free(empty_store);
00275 return s;
00276 }
00277
00278
00279
00280
00281 static ldns_status
00282 ldns_dane_get_nth_cert_from_validation_chain(
00283 X509** cert, STACK_OF(X509)* chain, int n, bool ca)
00284 {
00285 if (n >= sk_X509_num(chain) || n < 0) {
00286 return LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE;
00287 }
00288 *cert = sk_X509_pop(chain);
00289 while (n-- > 0) {
00290 X509_free(*cert);
00291 *cert = sk_X509_pop(chain);
00292 }
00293 if (ca && ! X509_check_ca(*cert)) {
00294 return LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
00295 }
00296 return LDNS_STATUS_OK;
00297 }
00298
00299
00300
00301
00302
00303 static ldns_status
00304 ldns_dane_pkix_get_last_self_signed(X509** out_cert,
00305 X509* cert, STACK_OF(X509)* extra_certs)
00306 {
00307 ldns_status s;
00308 X509_STORE* empty_store = NULL;
00309 X509_STORE_CTX* vrfy_ctx;
00310
00311 assert(out_cert != NULL);
00312
00313 empty_store = X509_STORE_new();
00314 s = LDNS_STATUS_SSL_ERR;
00315 vrfy_ctx = X509_STORE_CTX_new();
00316 if (! vrfy_ctx) {
00317 goto exit_free_empty_store;
00318
00319 } else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
00320 cert, extra_certs) != 1) {
00321 goto exit_free_vrfy_ctx;
00322
00323 }
00324 (void) X509_verify_cert(vrfy_ctx);
00325 if (vrfy_ctx->error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
00326 vrfy_ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT){
00327
00328 *out_cert = X509_STORE_CTX_get_current_cert( vrfy_ctx);
00329 s = LDNS_STATUS_OK;
00330 } else {
00331 s = LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR;
00332 }
00333 exit_free_vrfy_ctx:
00334 X509_STORE_CTX_free(vrfy_ctx);
00335
00336 exit_free_empty_store:
00337 X509_STORE_free(empty_store);
00338 return s;
00339 }
00340
00341
00342 ldns_status
00343 ldns_dane_select_certificate(X509** selected_cert,
00344 X509* cert, STACK_OF(X509)* extra_certs,
00345 X509_STORE* pkix_validation_store,
00346 ldns_tlsa_certificate_usage cert_usage, int offset)
00347 {
00348 ldns_status s;
00349 STACK_OF(X509)* pkix_validation_chain = NULL;
00350
00351 assert(selected_cert != NULL);
00352 assert(cert != NULL);
00353
00354
00355
00356
00357
00358
00359 if (pkix_validation_store == NULL) {
00360 switch (cert_usage) {
00361
00362 case LDNS_TLSA_USAGE_CA_CONSTRAINT:
00363
00364 cert_usage = LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION;
00365 break;
00366
00367 case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
00368
00369 cert_usage = LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE;
00370 break;
00371
00372 default:
00373 break;
00374 }
00375 }
00376
00377
00378
00379 switch (cert_usage) {
00380
00381 case LDNS_TLSA_USAGE_CA_CONSTRAINT:
00382
00383 s = ldns_dane_pkix_validate_and_get_chain(
00384 &pkix_validation_chain,
00385 cert, extra_certs,
00386 pkix_validation_store);
00387 if (! pkix_validation_chain) {
00388 return s;
00389 }
00390 if (s == LDNS_STATUS_OK) {
00391 if (offset == -1) {
00392 offset = 0;
00393 }
00394 s = ldns_dane_get_nth_cert_from_validation_chain(
00395 selected_cert, pkix_validation_chain,
00396 offset, true);
00397 }
00398 sk_X509_pop_free(pkix_validation_chain, X509_free);
00399 return s;
00400 break;
00401
00402
00403 case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
00404
00405 *selected_cert = cert;
00406 return ldns_dane_pkix_validate(cert, extra_certs,
00407 pkix_validation_store);
00408 break;
00409
00410
00411 case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
00412
00413 if (offset == -1) {
00414 s = ldns_dane_pkix_get_last_self_signed(
00415 selected_cert, cert, extra_certs);
00416 return s;
00417 } else {
00418 s = ldns_dane_pkix_get_chain(
00419 &pkix_validation_chain,
00420 cert, extra_certs);
00421 if (s == LDNS_STATUS_OK) {
00422 s =
00423 ldns_dane_get_nth_cert_from_validation_chain(
00424 selected_cert, pkix_validation_chain,
00425 offset, false);
00426 } else if (! pkix_validation_chain) {
00427 return s;
00428 }
00429 sk_X509_pop_free(pkix_validation_chain, X509_free);
00430 return s;
00431 }
00432 break;
00433
00434
00435 case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
00436
00437 *selected_cert = cert;
00438 return LDNS_STATUS_OK;
00439 break;
00440
00441 default:
00442 return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
00443 break;
00444 }
00445 }
00446
00447
00448 ldns_status
00449 ldns_dane_create_tlsa_rr(ldns_rr** tlsa,
00450 ldns_tlsa_certificate_usage certificate_usage,
00451 ldns_tlsa_selector selector,
00452 ldns_tlsa_matching_type matching_type,
00453 X509* cert)
00454 {
00455 ldns_rdf* rdf;
00456 ldns_status s;
00457
00458 assert(tlsa != NULL);
00459 assert(cert != NULL);
00460
00461
00462 *tlsa = ldns_rr_new_frm_type(LDNS_RR_TYPE_TLSA);
00463 if (*tlsa == NULL) {
00464 return LDNS_STATUS_MEM_ERR;
00465 }
00466
00467 rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
00468 (uint8_t)certificate_usage);
00469 if (rdf == NULL) {
00470 goto memerror;
00471 }
00472 (void) ldns_rr_set_rdf(*tlsa, rdf, 0);
00473
00474 rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)selector);
00475 if (rdf == NULL) {
00476 goto memerror;
00477 }
00478 (void) ldns_rr_set_rdf(*tlsa, rdf, 1);
00479
00480 rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)matching_type);
00481 if (rdf == NULL) {
00482 goto memerror;
00483 }
00484 (void) ldns_rr_set_rdf(*tlsa, rdf, 2);
00485
00486 s = ldns_dane_cert2rdf(&rdf, cert, selector, matching_type);
00487 if (s == LDNS_STATUS_OK) {
00488 (void) ldns_rr_set_rdf(*tlsa, rdf, 3);
00489 return LDNS_STATUS_OK;
00490 }
00491 ldns_rr_free(*tlsa);
00492 *tlsa = NULL;
00493 return s;
00494
00495 memerror:
00496 ldns_rr_free(*tlsa);
00497 *tlsa = NULL;
00498 return LDNS_STATUS_MEM_ERR;
00499 }
00500
00501
00502
00503
00504
00505 static ldns_rr_list*
00506 ldns_dane_filter_unusable_records(const ldns_rr_list* tlsas)
00507 {
00508 size_t i;
00509 ldns_rr_list* r = ldns_rr_list_new();
00510 ldns_rr* tlsa_rr;
00511
00512 if (! r) {
00513 return NULL;
00514 }
00515 for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
00516 tlsa_rr = ldns_rr_list_rr(tlsas, i);
00517 if (ldns_rr_get_type(tlsa_rr) == LDNS_RR_TYPE_TLSA &&
00518 ldns_rr_rd_count(tlsa_rr) == 4 &&
00519 ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0)) <= 3 &&
00520 ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1)) <= 1 &&
00521 ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2)) <= 2) {
00522
00523 if (! ldns_rr_list_push_rr(r, tlsa_rr)) {
00524 ldns_rr_list_free(r);
00525 return NULL;
00526 }
00527 }
00528 }
00529 return r;
00530 }
00531
00532
00533
00534
00535 static ldns_status
00536 ldns_dane_match_cert_with_data(X509* cert, ldns_tlsa_selector selector,
00537 ldns_tlsa_matching_type matching_type, ldns_rdf* data)
00538 {
00539 ldns_status s;
00540 ldns_rdf* match_data;
00541
00542 s = ldns_dane_cert2rdf(&match_data, cert, selector, matching_type);
00543 if (s == LDNS_STATUS_OK) {
00544 if (ldns_rdf_compare(data, match_data) != 0) {
00545 s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
00546 }
00547 ldns_rdf_free(match_data);
00548 }
00549 return s;
00550 }
00551
00552
00553
00554
00555
00556
00557 static ldns_status
00558 ldns_dane_match_any_cert_with_data(STACK_OF(X509)* chain,
00559 ldns_tlsa_selector selector,
00560 ldns_tlsa_matching_type matching_type,
00561 ldns_rdf* data, bool ca)
00562 {
00563 ldns_status s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
00564 size_t n, i;
00565 X509* cert;
00566
00567 n = (size_t)sk_X509_num(chain);
00568 for (i = 0; i < n; i++) {
00569 cert = sk_X509_pop(chain);
00570 if (! cert) {
00571 s = LDNS_STATUS_SSL_ERR;
00572 break;
00573 }
00574 s = ldns_dane_match_cert_with_data(cert,
00575 selector, matching_type, data);
00576 if (ca && s == LDNS_STATUS_OK && ! X509_check_ca(cert)) {
00577 s = LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
00578 }
00579 X509_free(cert);
00580 if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH) {
00581 break;
00582 }
00583
00584
00585
00586 }
00587 return s;
00588 }
00589
00590
00591 ldns_status
00592 ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
00593 X509* cert, STACK_OF(X509)* extra_certs,
00594 X509_STORE* pkix_validation_store)
00595 {
00596 ldns_status s;
00597
00598 STACK_OF(X509)* pkix_validation_chain = NULL;
00599
00600 ldns_tlsa_certificate_usage cert_usage;
00601 ldns_tlsa_selector selector;
00602 ldns_tlsa_matching_type matching_type;
00603 ldns_rdf* data;
00604
00605 if (! tlsa_rr) {
00606
00607
00608 return ldns_dane_pkix_validate(cert, extra_certs,
00609 pkix_validation_store);
00610 }
00611 cert_usage = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0));
00612 selector = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1));
00613 matching_type = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2));
00614 data = ldns_rr_rdf(tlsa_rr, 3) ;
00615
00616 switch (cert_usage) {
00617 case LDNS_TLSA_USAGE_CA_CONSTRAINT:
00618 s = ldns_dane_pkix_validate_and_get_chain(
00619 &pkix_validation_chain,
00620 cert, extra_certs,
00621 pkix_validation_store);
00622 if (! pkix_validation_chain) {
00623 return s;
00624 }
00625 if (s == LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
00626
00627
00628
00629
00630
00631
00632
00633
00634 s = ldns_dane_match_any_cert_with_data(
00635 pkix_validation_chain,
00636 selector, matching_type, data, true);
00637
00638 if (s == LDNS_STATUS_OK) {
00639
00640
00641
00642
00643 s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
00644 }
00645
00646 } else if (s == LDNS_STATUS_OK) {
00647
00648
00649 s = ldns_dane_match_any_cert_with_data(
00650 pkix_validation_chain,
00651 selector, matching_type, data, true);
00652 }
00653 sk_X509_pop_free(pkix_validation_chain, X509_free);
00654 return s;
00655 break;
00656
00657 case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
00658 s = ldns_dane_match_cert_with_data(cert,
00659 selector, matching_type, data);
00660
00661 if (s == LDNS_STATUS_OK) {
00662 return ldns_dane_pkix_validate(cert, extra_certs,
00663 pkix_validation_store);
00664 }
00665 return s;
00666 break;
00667
00668 case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
00669 s = ldns_dane_pkix_get_chain(&pkix_validation_chain,
00670 cert, extra_certs);
00671
00672 if (s == LDNS_STATUS_OK) {
00673 s = ldns_dane_match_any_cert_with_data(
00674 pkix_validation_chain,
00675 selector, matching_type, data, false);
00676
00677 } else if (! pkix_validation_chain) {
00678 return s;
00679 }
00680 sk_X509_pop_free(pkix_validation_chain, X509_free);
00681 return s;
00682 break;
00683
00684 case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
00685 return ldns_dane_match_cert_with_data(cert,
00686 selector, matching_type, data);
00687 break;
00688
00689 default:
00690 break;
00691 }
00692 return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
00693 }
00694
00695
00696 ldns_status
00697 ldns_dane_verify(ldns_rr_list* tlsas,
00698 X509* cert, STACK_OF(X509)* extra_certs,
00699 X509_STORE* pkix_validation_store)
00700 {
00701 size_t i;
00702 ldns_rr* tlsa_rr;
00703 ldns_status s = LDNS_STATUS_OK, ps;
00704
00705 assert(cert != NULL);
00706
00707 if (tlsas && ldns_rr_list_rr_count(tlsas) > 0) {
00708 tlsas = ldns_dane_filter_unusable_records(tlsas);
00709 if (! tlsas) {
00710 return LDNS_STATUS_MEM_ERR;
00711 }
00712 }
00713 if (! tlsas || ldns_rr_list_rr_count(tlsas) == 0) {
00714
00715
00716 return ldns_dane_pkix_validate(cert, extra_certs,
00717 pkix_validation_store);
00718 } else {
00719 for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
00720 tlsa_rr = ldns_rr_list_rr(tlsas, i);
00721 ps = s;
00722 s = ldns_dane_verify_rr(tlsa_rr, cert, extra_certs,
00723 pkix_validation_store);
00724
00725 if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH &&
00726 s != LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
00727
00728
00729
00730
00731
00732 break;
00733 }
00734 s = (s > ps ? s : ps);
00735
00736
00737 }
00738 ldns_rr_list_free(tlsas);
00739 }
00740 return s;
00741 }
00742 #endif