dane.c

Go to the documentation of this file.
00001 /*
00002  * Verify or create TLS authentication with DANE (RFC6698)
00003  *
00004  * (c) NLnetLabs 2012
00005  *
00006  * See the file LICENSE for the license.
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 /* Ordinary PKIX validation of cert (with extra_certs to help)
00158  * against the CA's in store
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 /* Orinary PKIX validation of cert (with extra_certs to help)
00192  * against the CA's in store, but also return the validation chain.
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 /* Return the validation chain that can be build out of cert, with extra_certs.
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 /* Pop n+1 certs and return the last popped.
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 /* Create validation chain with cert and extra_certs and returns the last
00301  * self-signed (if present).
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         /* With PKIX validation explicitely turned off (pkix_validation_store
00355          *  == NULL), treat the "CA constraint" and "Service certificate
00356          * constraint" the same as "Trust anchor assertion" and "Domain issued
00357          * certificate" respectively.
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         /* Now what to do with each Certificate usage...
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         /* create rr */
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 /* Return tlsas that actually are TLSA resource records with known values
00503  * for the Certificate usage, Selector and Matching type rdata fields.
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 /* Return whether cert/selector/matching_type matches data.
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 /* Return whether any certificate from the chain with selector/matching_type
00554  * matches data.
00555  * ca should be true if the certificate has to be a CA certificate too.
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                 /* when s == LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
00584                  * try to match the next certificate
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                 /* No TLSA, so regular PKIX validation
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                          * NO PKIX validation. We still try to match *any*
00628                          * certificate from the chain, so we return
00629                          * TLSA errors over PKIX errors.
00630                          *
00631                          * i.e. When the TLSA matches no certificate, we return
00632                          * TLSA_DID_NOT_MATCH and not PKIX_DID_NOT_VALIDATE
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                                 /* A TLSA record did match a cert from the
00640                                  * chain, thus the error is failed PKIX
00641                                  * validation.
00642                                  */
00643                                 s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
00644                         }
00645 
00646                 } else if (s == LDNS_STATUS_OK) { 
00647                         /* PKIX validated, does the TLSA match too? */
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                 /* No TLSA's, so regular PKIX validation
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                                 /* which would be LDNS_STATUS_OK (match)
00729                                  * or some fatal error preventing use from
00730                                  * trying the next TLSA record.
00731                                  */
00732                                 break;
00733                         }
00734                         s = (s > ps ? s : ps); /* prefer PKIX_DID_NOT_VALIDATE
00735                                                 * over   TLSA_DID_NOT_MATCH
00736                                                 */
00737                 }
00738                 ldns_rr_list_free(tlsas);
00739         }
00740         return s;
00741 }
00742 #endif /* HAVE_SSL */

Generated on Wed Dec 19 16:56:49 2012 for ldns by  doxygen 1.4.7