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