]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSCore/dnssec.h
mDNSResponder-878.200.35.tar.gz
[apple/mdnsresponder.git] / mDNSCore / dnssec.h
1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #ifndef __DNSSEC_H
19 #define __DNSSEC_H
20
21 #include "CryptoAlg.h"
22 #include "mDNSDebug.h"
23
24 typedef enum
25 {
26 RRVS_rr, RRVS_rrsig, RRVS_key, RRVS_rrsig_key, RRVS_ds, RRVS_done,
27 } RRVerifierSet;
28
29 typedef struct RRVerifier_struct RRVerifier;
30 typedef struct DNSSECVerifier_struct DNSSECVerifier;
31 typedef struct AuthChain_struct AuthChain;
32 typedef struct InsecureContext_struct InsecureContext;
33
34 struct RRVerifier_struct
35 {
36 RRVerifier *next;
37 mDNSu16 rrtype;
38 mDNSu16 rrclass;
39 mDNSu32 rroriginalttl;
40 mDNSu16 rdlength;
41 mDNSu16 found;
42 mDNSu32 namehash;
43 mDNSu32 rdatahash;
44 domainname name;
45 mDNSu8 *rdata;
46 };
47
48 // Each AuthChain element has one rrset (with multiple resource records of same type), rrsig and key
49 // that validates the rrset.
50 struct AuthChain_struct
51 {
52 AuthChain *next; // Next element in the chain
53 RRVerifier *rrset; // RRSET that is authenticated
54 RRVerifier *rrsig; // Signature for that RRSET
55 RRVerifier *key; // Public key for that RRSET
56 };
57
58 #define ResetAuthChain(dv) { \
59 (dv)->ac = mDNSNULL; \
60 (dv)->actail = &((dv)->ac); \
61 }
62
63 typedef void DNSSECVerifierCallback (mDNS *const m, DNSSECVerifier *dv, DNSSECStatus status);
64 //
65 // When we do a validation for a question, there might be additional validations that needs to be done e.g.,
66 // wildcard expanded answer. It is also possible that in the case of nsec we need to prove both that a wildcard
67 // does not apply and the closest encloser proves that name does not exist. We identify these with the following
68 // flags.
69 //
70 // Note: In the following, by "marking the validation", we mean that as part of validation we need to prove
71 // the ones that are marked with.
72 //
73 // A wildcard may be used to answer a question. In that case, we need to verify that the right wildcard was
74 // used in answering the question. This is done by marking the validation with WILDCARD_PROVES_ANSWER_EXPANDED.
75 //
76 // Sometimes we get a NXDOMAIN response. In this case, we may have a wildcard where we need to prove
77 // that the wildcard proves that the name does not exist. This is done by marking the validation with
78 // WILDCARD_PROVES_NONAME_EXISTS.
79 //
80 // In the case of NODATA error, sometimes the name may exist but the query type does not exist. This is done by
81 // marking the validation with NSEC_PROVES_NOTYPE_EXISTS.
82 //
83 // In both NXDOMAIN and NODATA proofs, we may have to prove that the NAME does not exist. This is done by marking
84 // the validation with NSEC_PROVES_NONAME_EXISTS.
85 //
86 #define WILDCARD_PROVES_ANSWER_EXPANDED 0x00000001
87 #define WILDCARD_PROVES_NONAME_EXISTS 0x00000002
88 #define NSEC_PROVES_NOTYPE_EXISTS 0x00000004
89 #define NSEC_PROVES_NONAME_EXISTS 0x00000008
90 #define NSEC3_OPT_OUT 0x00000010 // OptOut was set in NSEC3
91
92 struct DNSSECVerifier_struct
93 {
94 domainname origName; // Original question name that needs verification
95 mDNSu16 origType; // Original question type corresponding to origName
96 mDNSu16 currQtype; // Current question type that is being verified
97 mDNSInterfaceID InterfaceID; // InterfaceID of the question
98 DNSQuestion q;
99 mDNSu8 recursed; // Number of times recursed during validation
100 mDNSu8 ValidationRequired; // Copy of the question's ValidationRequired status
101 mDNSu8 InsecureProofDone;
102 mDNSu8 NumPackets; // Number of packets that we send on the wire for DNSSEC verification.
103 mDNSs32 StartTime; // Time the DNSSEC verification starts
104 mDNSu32 flags;
105 RRVerifierSet next;
106 domainname *wildcardName; // set if the answer is wildcard expanded
107 RRVerifier *pendingNSEC;
108 DNSSECVerifierCallback *DVCallback;
109 DNSSECVerifier *parent;
110 RRVerifier *rrset; // rrset for which we have to verify
111 RRVerifier *rrsig; // RRSIG for rrset
112 RRVerifier *key; // DNSKEY for rrset
113 RRVerifier *rrsigKey; // RRSIG for DNSKEY
114 RRVerifier *ds; // DS for DNSKEY set in parent zone
115 AuthChain *saveac;
116 AuthChain *ac;
117 AuthChain **actail;
118 AlgContext *ctx;
119 };
120
121
122 struct InsecureContext_struct
123 {
124 DNSSECVerifier *dv; // dv for which we are doing the insecure proof
125 mDNSu8 skip; // labels to skip for forming the name from origName
126 DNSSECStatus status; // status to deliver when done
127 mDNSu8 triggerLabelCount; // Label count of the name that triggered the insecure proof
128 DNSQuestion q;
129 };
130
131 #define LogDNSSEC LogOperation
132
133 #define DNS_SERIAL_GT(a, b) ((int)((a) - (b)) > 0)
134 #define DNS_SERIAL_LT(a, b) ((int)((a) - (b)) < 0)
135
136 extern void StartDNSSECVerification(mDNS *const m, void *context);
137 extern RRVerifier* AllocateRRVerifier(const ResourceRecord *const rr, mStatus *status);
138 extern mStatus AddRRSetToVerifier(DNSSECVerifier *dv, const ResourceRecord *const rr, RRVerifier *rv, RRVerifierSet set);
139 extern void VerifySignature(mDNS *const m, DNSSECVerifier *dv, DNSQuestion *q);
140 extern void FreeDNSSECVerifier(mDNS *const m, DNSSECVerifier *dv);
141 extern DNSSECVerifier *AllocateDNSSECVerifier(mDNS *const m, const domainname *name, mDNSu16 rrtype, mDNSInterfaceID InterfaceID,
142 mDNSu8 ValidationRequired, DNSSECVerifierCallback dvcallback, mDNSQuestionCallback qcallback);
143 extern void InitializeQuestion(mDNS *const m, DNSQuestion *question, mDNSInterfaceID InterfaceID, const domainname *qname,
144 mDNSu16 qtype, mDNSQuestionCallback *callback, void *context);
145 extern void ValidateRRSIG(DNSSECVerifier *dv, RRVerifierSet type, const ResourceRecord *const rr);
146 extern void AuthChainLink(DNSSECVerifier *dv, AuthChain *ae);
147 extern mStatus DNSNameToLowerCase(domainname *d, domainname *result);
148 extern int DNSMemCmp(const mDNSu8 *const m1, const mDNSu8 *const m2, int len);
149 extern int DNSSECCanonicalOrder(const domainname *const d1, const domainname *const d2, int *subdomain);
150 extern void ProveInsecure(mDNS *const m, DNSSECVerifier *dv, InsecureContext *ic, domainname *trigger);
151 extern void BumpDNSSECStats(mDNS *const m, DNSSECStatsAction action, DNSSECStatsType type, mDNSu32 value);
152 extern char *DNSSECStatusName(DNSSECStatus status);
153
154 // DNSSECProbe belongs in DNSSECSupport.h but then we don't want to expose yet another plaform specific dnssec file
155 // to other platforms where dnssec is not supported.
156 extern void DNSSECProbe(mDNS *const m);
157
158 #endif // __DNSSEC_H