1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
|
# Copyright 2004-2012 SPARTA, Inc. All rights reserved.
# See the COPYING file included with the dnssec-tools package for details.
DNSSEC-Tools
Is your domain secure?
DNSSEC validator
----------------
The libval(3) library provides basic functionality for resource-record
validation. It relies on the resolver component (see
libsres-implementation-notes for more details) to fetch answers from a
DNSSEC-aware name server.
Overview
-------
The security extensions to DNS allows applications to test the authenticity of
data returned by the DNS. The validator library performs this test by checking
the cryptographic signatures that cover DNS records and by building a sequence
of such verified records up to a trusted key. The library exports a number of
basic interfaces that applications may use in lieu of older resolver interfaces
provided by the libres(3) library. Other interfaces are also provided that
allow applications more detail into the validation process. This range allows
for the creation of applications that are either only interested in a basic
"validated" or "not-validated" result, or more sophisticated applications that
can look for specific errors as a sign of some network abnormality or attack.
See libval(3), val_gethostbyname(3), val_getaddrinfo(3), val_res_query(3) and
val_get_rrset(3) for the interfaces are exported by the validator.
The validator supports the RSA/MD5 [RFC_2537], DSA/SHA-1 [RFC_2536] and
RSA/SHA-1 [RFC_3110] DNSSEC algorithms. It uses the OpenSSL software package
for cryptographic processing.
Validator Design Choices
------------------------
1. Trusted versus validated conditions
The DNSSEC specification lists four validation states: success, bogus,
indeterminate and provably insecure. While the validator library is
able to gather details of each of these conditions by inspecting the
authentication chain, most applications are only interested in a high-level
answer that tells it if the response was trustworthy or not. Since
the bogus and indeterminate states are effectively equivalent, the DNSSEC
specification really only allows for three conditions - Validated, Untrusted,
Provably Insecure.
The provably insecure condition is interesting, since some applications
may view this as untrusted, while others may view this as a directive
by the parent to say that there is no security expectation for the child,
in which the answer is trustworthy. Validation policy may also specify
all answers from a zone to be either trustworthy or untrustworthy.
In view of the above considerations, the validator library defines three
high-level states for answers - trusted, validated, and untrusted.
The validated condition covers all the states where an answer was
cryptographically validated from a locally configured trust anchor.
The trusted condition covers those states that are validated, and
also those states that are locally trusted. All other conditions
are untrusted.
A negative proof may similarly be trusted, validated or untrusted.
The provably insecure condition may be configured by local policy
to either be trusted or not.
2. Top-down versus bottom-up validation
There are two possible ways in which a validator may construct its
authentication chain: top-down and bottom-up. Top-down validation uses the
normative query process to also fetch and validate DNSSEC meta-data,
chaining down from a known trust anchor. Bottom-up validation builds the
authentication chain from the data to a known trust anchor.
For a security-aware recursive name server, the top-down approach is generally
more efficient. For a validating end-system, the type of data that must be
validated decides which approach is more efficient. The reason for this is that
validating end-systems are very often located behind some caching name server
In order to utilize the benefits provided by the DNS caching infrastructure,
the validating stub resolver must not attempt to recursively answer all
queries itself. Furthermore, firewall configurations in may environments
also run recursive name server processes that preempt any attempt made
by the end system to run in recursive mode.
With this architecture in mind, the problems with top-down validation become
evident. In order for top-down validation to work, the validator must be able
reconstruct the list of zonecuts all the way down from the trust anchor to the
query. It must do so by issuing SOA queries for the list of names obtained by
adding labels present in the query to the zone name configured as the trust
anchor, in succession, until the zonecut information can be determined, and
repeat this process till the zonecut covering the original query is reached.
Bottom-up validation does not suffer from this problem to the extent that
zonecut information for is already available via the RRSIG meta-data.
The above reasoning holds only if zones are signed most of the time. If
signatures are missing, the validator would have to perform a similar but
less query-intensive process of determining if the zone that lacked DNSSEC
meta-data was actually provably insecure. The provably insecure check is
straightforward to perform if validation happens top-down.
Using the above rationale, the libval library has been designed to do
bottom-up validation by default and then switch over to top-down validation
in case a provably insecure condition needs to be checked.
3. Multi-threading support (sharing validator contexts)
Multi-threaded applications should be able to share validator contexts.
The constraints to doing this is that data can time out. However the
specifications say that data must be kept for the duration of the
validation check (even if the TTL expires). Another constraint is that
multiple threads can issue the same query at the same time.
The design choices for context sharing are impacted by the following
concerns:
- Extent of sharing: applications that are able to access a
validator context that is being used by some other application
has security implications
- lock granularity: overhead of acquiring locks for each assertion
chain element v/s typical operation of single threaded app
- posix does not allow lock upgrade and downgrade
The following design choices were made for the validator:
- "hold" relevant queries till such time that validate
does not complete (queries_for_query structure)
- queries can be deleted only if there is no qfq pointing to it.
This is determined through the qc_refcount field in val_query_chain.
- Locking strategy
- CTX_LOCK_ACACHE : Mutex to ensure that only one thread can modify
the context policies or cache at a given point in time.
- VAL_CACHE_LOCK : R/W lock to ensure that the context-independent
resolver cache is only modified when no other thread is reading
data from it.
- CTX_LOCK_POL : R/W lock to ensure that the context is not released
while it is still being used by another thread.
- LOCK_DEFAULT_CONTEXT : Mutex to ensure that the default context is
not modified while it is being accessed in another thread.
//This impacts the resolver logic in that libsres should never block
//also imply that we are not able to log query-related information since
//this is unreliable after a call to the validator functions (queries may
//time out).
4. NULL contexts
All functions exported by libval have their first parameter as a
"validator context". The context provides a handle to the validation
policy as selected by the application. Since the results of validation
depend on validator policy, the context also provides the handle to cached
authentication chains. The expected usage is that applications will create
a context using the val_create_context() function and supply this value to
different functions so that the results of validation are reused.
Successive calls to val_create_context() create fresh context objects,
even if they were created using the same label. This allows applications to
be able to validate using the same policy but without reusing
older validation results.
libval also allows applications that are DNSSEC-agnostic to supply a NULL
context for different functions. In such cases libval will create a
temporary context using some default policy. However, if this context is
deleted after use, it would mean that DNSSEC-agnostic applications will
never be able to make use of the benefit of validator caches
In order to account for this we special case the handling of NULL labels
during context creation. Instead of creating a fresh context each time
a NULL argument is given, libval will return a saved value if
the context was already created in the past. This behavior is for NULL
labels only (and not even for contexts created using the ":" label). in
other words, successive calls to val_create_contex(":",...) will still
create fresh contexts. The rationale here is that applications that
know what value to pass as a non-NULL label should also be intelligent
enough to reuse context objects that they create.
5. Environment overrides for validator policy
While it is always possible to write an application that uses a specific
validator policy (or allow the user to supply one through a command line
option), we wanted to provide a less intrusive way for users to specify
a validation policy to libval. There were two approaches that we came up
with - reading the policy label from an variable, and dynamically
generating the policy label from the application name.
locked-down system with single policy
An administrator that wants to (and is able to) lock down a
system to a particular validator policy, must be able to
disable other ways for a user to change the validator
policy
locked-down system with app-specific policies
An administrator that wants to (and is able to) lock down a
system to a particular dnsval.conf file, but wishes to use dif-
ferent policies for different applications must still be allowed
to disable reading policy labels from the environment.
User controlled
It must be possible for an administrator to give complete
flexibility to the user over the choice of policy label,
either on a per-application basis or on a system-wide basis.
The set of precedence rules are documented in dnsval.conf(3)
6. Minimizing false positives
While constructing the chain of trust we are willing to look at more trust
anchors when trying to verify a proof. When trying to prove that DNSSEC is
not required (through the provably insecure condition), we only look at the
closest matching trust anchor.
7. Fallback and recovery
During the initial years of DNSSEC deployment there are expected to be various
cases where a DNSSEc validator will encounter a response returned from a
DNSSEC-unaware name server. While the DNSSEC specifications state the
"clear-path" requirement where there is an expectation that all name servers
along the validation path must be DNSSEC-aware, from a user-experience perspective,
it behooves the validator to do some sort of fallback in order to route around
such (temporarily broken or badly behaving) middle boxes. libval has the
following fallback and recovery strategy:
a) Resolver fallback
libval (via libsres) will send queries in parallel to all name servers
listed in the NSset, staggering the queries every five seconds. Thus
it will only return a DNS error if all name servers fail to answer the query.
See libsres-implementation-notes for additional details.
b) EDNS0 fallback
In querying various name servers, libsres will also attempt multiple EDNS0
sizes, ending with a query that has EDNS0 disabled (i.e. no CD bit set).
The following EDNS0 sizes are tried by default: 4096, 1492, 512
The "edns0-size" policy knob in dnsval.conf can be used to change the
largest EDNS0 size that is attempted.
c) Validation error fallback
If the validator encounters a validation failure it will re-attempt the
lookup, but this time recursing from root (unless it is already recursively
looking up the name in which case this fallback is not attempted). This
gives libval the opportunity to recover from failure scenarios where the recursive
name server is lying or is broken DNSSEC-wise, but also allows libval to use
the caching properties of the recursive name server to the extent possible.
Validator Algorithm
-------------------
The val_resolve_and_check() interface forms the core interface for the
validator library. Its algorithm is as follows:
i) A new validator context is created if one does not exist already.
ii) The next step in val_resolve_and_check() is to build a data request
entry for the missing data. The data request entry is stored in the
"queries" linked list which is of type "struct queries_for_query".
Each element in this linked list internally maps to an element in
another linked list of type 'struct val_query_chain'.
The queries linked list is created separately for each call to
val_resolve_and_check. The val_query_chain linked list is maintained
on a per-context basis and is the "query cache" for the context.
iii)Not all data requests get translated into actual DNS queries; some
answers may be obtained from the local cache. Answers are always
accessed through the struct val_query_chain element. This is because, data may
time out. The struct val_query_chain element maintains the state
of the response; if it times out the query state will revert to the
initial state.
iv) For every answer that is received, the validator assimilates this data
and identifies any additional queries need to be made in order to
either verify the data contained in the response or to build the chain-
of-trust to a trust anchor. Assimilated data is stored in the "struct
val_digested_auth_chain" structure, which is also a linked list. A
separate data request entry is created for each such data component
that is required and all of them are added to the "queries"
linked-list. The val_digested_auth_chain linked list is also maintained
on a per-context basis.
v) Data contained in an element of the authentcation chain can be verified
as long as all cryptographic components necessary to complete this
operation is available. The verification operation may be
performed even if other components in the chain of trust are still
being built.
vi) Since multiple RRsets may be returned in response to a query there
can be multiple authentication chains that are returned.
Multiple authentication chains are also possible for negative
proofs where the proof is actually comprised of an SOA RR, and one
or more NSEC (or NSEC3) RRsets. Multiple answers are represented
through multiple elements in the struct val_internal_result linked
list. Each val_internal_result element wraps around an authentication
chain. It points to the chain and also contains a consolidated
validation status value for the authentication chain.
vii)For RRsets in the response that are not validated, the validator may
selectively perform the DLV logic to identify if the data can be validated
that way. The DLV logic is only applied if the entry point from the DLV
tree to the main tree is at a closer point to the query name than any
configured trust anchor for the main tree.
viii) For status values that map to unsuccessful conditions, an attempt is
made to see if the answer is actually provably insecure. This test
test is made in a top-down fashion starting from the closest configured
trust anchor and ending at the zone cut for the query in question.
viii)Steps iii) through viii) are repeated as long as there are additional
queries that have still not received a response or failure from the
DNS. Upon completion, the authentication chain linked list contains the
list of all answers that were returned from the DNS with a field
describing each of their validation status values and a consolidated
validation status value for the entire authentication chain. If no
answers were returned or some DNS error was encountered for a particular
query, an empty authentication chain node is created to contain this
error value.
ix) Once all authentication chains have been completed, a number of
sanity checks are performed on the elements of the .
- Any non-existence proofs are checked at this time, but only
if all components of the proof are trustworthy.
- Wildcard responses are checked to see if they actually expand
the correct type and the original name itself does not exist.
- Any CNAME and DNAME chains are checked to ensure that they
are loop-free and that they are complete. If the final element
in a CNAME or DNAME chain is also an alias then any proof of
non-existence is checked to ensure that the name being pointed
to is provably non-existent.
Each element in the val_internal_result linked list that has passed
the sanity check above is converted to a similar entry in the
val_result_chain linked list. The elements in the val_result_chain
linked list (including the authentication chain elements) are copied
indivually from their val_internal_result counterparts; they are
not merely a reference.
x) Any left over elements in the val_internal_result linked list that
have not been consumed by the above sanity check process is transformed
into a similar entry into the val_result_chain linked list. If the element
is a component of a proof of non-existence it is considered extraneous
and marked as bogus.
xi) The val_resolve_and_check() method returns the val_result_chain
to the calling application only if the application has requested this
information.
Lower-level routines: digesting answers received from libsres
-------------------------------------------------------------
The validator uses the asynchronous query_send() and response_rcv()
resolver interfaces (see man page for libsres(3)) to fetch answers from the DNS.
The D0 and CD bit on the query is only set if a trust anchor is configured
above the name being queried for. Note that since checks for the provably
insecure condition are not made as the referral is being traversed, the
D0 and CD bits are also set while issuing queries for names that are under
a provably insecure domain.
After the answer is received, the first step is "digesting" the response --
RRsets in the answer and authority sections are extracted as is any
referral information present in the additional section of the response. Any
DS or DNSKEY information is also cached for future use. One aspect
of the caching functionality that will change in future is the notion of
credibility of data stored within the cache.
The validator follows any referrals or aliases that are returned as part of
the response and issues queries to fetch any missing glue. Information gathered
as part of following referrals are maintained separately within the val_query_chain
structure. Once the referral operation completes, all information within
this entry are merged into the validator cache.
The validator keeps track of nameservers that it actually used while following
referrals. These are re-used in future requests for data in the same zone.
Digestion of answers is followed by assimilation of answers. Here, the data
returned by the digestion process is transformed into an authentication chain
element. Checks are made to determine the answer kind and if the data or NSEC
was actually relevant. A sanity check is also made to ensure that all answers
received as part of a query with type as ANY have the same answer kind.
Query, Assertion and Result states
----------------------------------
Query states transition as follows:
(cached)
+------------>Q_ANSWERED
| ^
| | (answer recieved)
| |
| |
| (query sent) | (error)
Q_INIT ----------> Q_SENT --------> (Q_ERROR_BASE + <error_condition>)
^ | | ^
| | | |
+<---------------+ | |
| (referral) | |
| | |
| | |
| (success) v (fail) |
+<----------- Q_WAIT_FOR_GLUE ---------+
(A|AAAA)
Query Flags
-----------
Cached assertions for a given validator context are accessed through
the handle from the corresponding val_query_chain structure. The
add_to_query_chain() functions provides the mechanism to locate the
particular val_query_chain object (if it exists in the context cache)
to the corresponds to a give name,type,class tuple.
Applications, however, can be multi-threaded and can issue parallel
lookup operations from multiple threads using the same validator
context. In order to ensure that the correct locking semantics are
preserved for all auxillary queries issued as part of validating
the primary name, the validator tracks this information through
the queries_for_query linked list. This list is merely a linked
list of handles to the various val_query_chain objects associated
with the query. If a query_for_query_chain object exists, a
corresponding val_query_chain object MUST exist.
The query behaviour for a particular lookup operation is guided by
the query flags set for that query. The queries_for_structure contains
the qfq_flags member while the val_query_chain structure contains the
qc_flags member. While the values that can be saved in these variables
are the same there is a subtle difference in the usage of these flags.
All query flags specified by the user are stored in the qfq_flags
member. libval uses the VAL_QFLAGS_USERMASK mask to ensure that the
flags specified by the user are acceptible. libval then uses these flags
to look for cached val_query_chain structures in the context cache
and sets and resets other internal flags as necessary while resolving
this name. Not all flags are matched while checking for cached
val_query_chain structures -- the VAL_QFLAGS_CACHE_MASK,
VAL_QFLAGS_CACHE_PREF_MASK and VAL_QFLAGS_NOCACHE_MASK bitmasks select
those flags that are relevant for the given query. Not all
val_query_chain objects referenced with a query_for_query list
will match the qfq_flags value.
A useful rule-of-thumb while deciding whether to use qfq_flags
or qc_flags in a partular line of code is the following -- While
setting the flags for any query use qfq_flags; When testing for
a particular flag use qc_flags.
===============================================================================================
Assertion states transition as follows:
VAL_AC_UNSET
|
v
VAL_AC_INIT
|
+-----------------> VAL_AC_TRUST_NOCHK --------------------------------------->+
| |
| +-----------------------+ |
+----------------->| VAL_AC_NEGATIVE_PROOF |----------------------------------->+
| +-----------------------+ |
| |
+-----------------> VAL_AC_WAIT_FOR_RRSIG --------+ |
| | | |
| | v |
| | +==============+ |
| | | ERROR |----------------->|
| | +==============+ |
| | ^ |
| v | |
+-----------------> VAL_AC_WAIT_FOR_TRUST --------+ |
| | |
| | |
| v +==============+ |
| VAL_AC_CAN_VERIFY ----> | SUCCESS | |
| | +==============+ |
| | |
| | |
| v |
| VAL_AC_FAIL_BASE +====================+ |
+-------||----------->| FAIL | ---------------------------------->+
| VAL_AC_LAST_FAILURE +====================+ |
| |
| |
| |
| VAL_AC_BAD_BASE +====================+ |
+-------||----------->| BAD | |
| VAL_AC_LAST_BAD +====================+ |
| |
| |
| |
| |
|<----------------------------------------------------------------------------->+
|
v
+====================+
| DONT GO FURTHER |
+====================+
where:
+====================+
| DONT GO FURTHER |
+====================+
|---> VAL_AC_IGNORE_VALIDATION
|---> VAL_AC_UNTRUSTED_ZONE
|---> VAL_AC_PINSECURE
|---> VAL_AC_BARE_RRSIG
|---> VAL_AC_NO_LINK
+---> VAL_AC_TRUST
+====================+
| ERROR |
+====================+
|---> VAL_AC_RRSIG_MISSING
|---> VAL_AC_DNSKEY_MISSING
+---> VAL_AC_DS_MISSING
+====================+
| BAD |
+====================+
|---> VAL_AC_DATA_MISSING
+---> VAL_AC_DNS_ERROR
+====================+
| FAIL |
+====================+
|
|---> VAL_AC_NOT_VERIFIED
|
|---> DS status
| |-------------> VAL_AC_INVALID_DS
| +-------------> VAL_AC_ALGORITHM_NOT_SUPPORTED
|
|---> Key status
| |-------------> VAL_AC_UNKNOWN_DNSKEY_PROTOCOL
| |-------------> VAL_AC_DS_NOMATCH
| |-------------> VAL_AC_INVALID_KEY
| +-------------> VAL_AC_ALGORITHM_NOT_SUPPORTED
|
+---> sig status
|-------------> VAL_AC_WRONG_LABEL_COUNT
|-------------> VAL_AC_INVALID_RRSIG
|-------------> VAL_AC_RRSIG_NOTYETACTIVE
|-------------> VAL_AC_RRSIG_EXPIRED
|-------------> VAL_AC_RRSIG_VERIFY_FAILED
|-------------> VAL_AC_RRSIG_ALGORITHM_MISMATCH
|-------------> VAL_AC_DNSKEY_NOMATCH
+-------------> VAL_AC_ALGORITHM_NOT_SUPPORTED
+====================+
| SUCCESS |
+====================+
|
|---> VAL_AC_VERIFIED
|
|---> Key status
| |-------------> VAL_AC_TRUST_POINT
| |-------------> VAL_AC_SIGNING_KEY
| |-------------> VAL_AC_VERIFIED_LINK
| +-------------> VAL_AC_UNKNOWN_ALGORITHM_LINK
|
+---> sig status
|
|-------------> VAL_AC_RRSIG_VERIFIED
|-------------> VAL_AC_WCARD_VERIFIED
|-------------> VAL_AC_RRSIG_VERIFIED_SKEW
+-------------> VAL_AC_WCARD_VERIFIED_SKEW
The consolidated dnssec validation results obtained in the results array
are derived from the authentication chain states in the following manner:
(Note: see val_errors.h for values of *_BASE and *_LAST)
VAL_OOB_ANSWER is returned if an answer is returned from some non-DNS database
such as /etc/hosts.
any auth.chain.elem result
status status
====================================================
> FAIL_BASE, VAL_BOGUS
<=LAST_FAILURE
VAL_AC_DNS_ERROR VAL_DNS_ERROR
VAL_AC_DATA_MISSING VAL_DNS_ERROR
VAL_AC_BARE_RRSIG VAL_BARE_RRSIG
VAL_AC_IGNORE_VALIDATION VAL_IGNORE_VALIDATION
VAL_AC_UNTRUSTED_ZONE VAL_UNTRUSTED_ZONE
top-as every final result status
status status
============================================================================
VAL_AC_TRUST VERIFIED VAL_SUCCESS
VAL_AC_NO_LINK VERIFIED VAL_NOTRUST
The following status values are defined for results of negative proof checks for
the main DNS query:
Condition final result
==========================================================================
All components of the proof of VAL_NONEXISTENT_NAME
non-existence, also validated or VAL_NONEXISTENT_TYPE
All components of the proof of VAL_NONEXISTENT_NAME_NOCHAIN
non-existence, trusted but or VAL_NONEXISTENT_TYPE_NOCHAIN
not validated
Any component of the proof of VAL_BOGUS
non-existence is not trusted
or proof components are trusted
but are incomplete
For negative proofs in the middle of the authentication chain, if
the check for provably insecure condition could not be performed, the
status is set to VAL_BOGUS_PROOF.
For the VAL_AC_PINSECURE condition, the following values exist:
Provably insecure trust status final result
==========================================================================
Trusted VAL_PINSECURE
Untrusted VAL_PINSECURE_UNTRUSTED
Acknowledgements
----------------
Some of the code for this library was borrowed from an older implementation
of the secure resolver library written by Ed Lewis at Tislabs.
|