1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "CryptoAlg.h"
21 #include "mDNSDebug.h"
25 RRVS_rr
, RRVS_rrsig
, RRVS_key
, RRVS_rrsig_key
, RRVS_ds
, RRVS_done
,
28 typedef struct RRVerifier_struct RRVerifier
;
29 typedef struct DNSSECVerifier_struct DNSSECVerifier
;
30 typedef struct AuthChain_struct AuthChain
;
31 typedef struct InsecureContext_struct InsecureContext
;
33 struct RRVerifier_struct
38 mDNSu32 rroriginalttl
;
47 // Each AuthChain element has one rrset (with multiple resource records of same type), rrsig and key
48 // that validates the rrset.
49 struct AuthChain_struct
51 AuthChain
*next
; // Next element in the chain
52 RRVerifier
*rrset
; // RRSET that is authenticated
53 RRVerifier
*rrsig
; // Signature for that RRSET
54 RRVerifier
*key
; // Public key for that RRSET
57 #define ResetAuthChain(dv) { \
58 (dv)->ac = mDNSNULL; \
59 (dv)->actail = &((dv)->ac); \
62 typedef void DNSSECVerifierCallback (mDNS
*const m
, DNSSECVerifier
*dv
, DNSSECStatus status
);
64 // When we do a validation for a question, there might be additional validations that needs to be done e.g.,
65 // wildcard expanded answer. It is also possible that in the case of nsec we need to prove both that a wildcard
66 // does not apply and the closest encloser proves that name does not exist. We identify these with the following
69 // Note: In the following, by "marking the validation", we mean that as part of validation we need to prove
70 // the ones that are marked with.
72 // A wildcard may be used to answer a question. In that case, we need to verify that the right wildcard was
73 // used in answering the question. This is done by marking the validation with WILDCARD_PROVES_ANSWER_EXPANDED.
75 // Sometimes we get a NXDOMAIN response. In this case, we may have a wildcard where we need to prove
76 // that the wildcard proves that the name does not exist. This is done by marking the validation with
77 // WILDCARD_PROVES_NONAME_EXISTS.
79 // In the case of NODATA error, sometimes the name may exist but the query type does not exist. This is done by
80 // marking the validation with NSEC_PROVES_NOTYPE_EXISTS.
82 // In both NXDOMAIN and NODATA proofs, we may have to prove that the NAME does not exist. This is done by marking
83 // the validation with NSEC_PROVES_NONAME_EXISTS.
85 #define WILDCARD_PROVES_ANSWER_EXPANDED 0x00000001
86 #define WILDCARD_PROVES_NONAME_EXISTS 0x00000002
87 #define NSEC_PROVES_NOTYPE_EXISTS 0x00000004
88 #define NSEC_PROVES_NONAME_EXISTS 0x00000008
89 #define NSEC3_OPT_OUT 0x00000010 // OptOut was set in NSEC3
91 struct DNSSECVerifier_struct
93 domainname origName
; // Original question name that needs verification
94 mDNSu16 origType
; // Original question type corresponding to origName
95 mDNSu16 currQtype
; // Current question type that is being verified
96 mDNSInterfaceID InterfaceID
; // InterfaceID of the question
98 mDNSu8 recursed
; // Number of times recursed during validation
99 mDNSu8 ValidationRequired
; // Copy of the question's ValidationRequired status
100 mDNSu8 InsecureProofDone
;
101 mDNSu8 NumPackets
; // Number of packets that we send on the wire for DNSSEC verification.
102 mDNSs32 StartTime
; // Time the DNSSEC verification starts
105 domainname
*wildcardName
; // set if the answer is wildcard expanded
106 RRVerifier
*pendingNSEC
;
107 DNSSECVerifierCallback
*DVCallback
;
108 DNSSECVerifier
*parent
;
109 RRVerifier
*rrset
; // rrset for which we have to verify
110 RRVerifier
*rrsig
; // RRSIG for rrset
111 RRVerifier
*key
; // DNSKEY for rrset
112 RRVerifier
*rrsigKey
; // RRSIG for DNSKEY
113 RRVerifier
*ds
; // DS for DNSKEY set in parent zone
121 struct InsecureContext_struct
123 DNSSECVerifier
*dv
; // dv for which we are doing the insecure proof
124 mDNSu8 skip
; // labels to skip for forming the name from origName
125 DNSSECStatus status
; // status to deliver when done
126 mDNSu8 triggerLabelCount
; // Label count of the name that triggered the insecure proof
130 #define LogDNSSEC LogOperation
132 #define DNS_SERIAL_GT(a, b) ((int)((a) - (b)) > 0)
133 #define DNS_SERIAL_LT(a, b) ((int)((a) - (b)) < 0)
135 extern void StartDNSSECVerification(mDNS
*const m
, void *context
);
136 extern RRVerifier
* AllocateRRVerifier(const ResourceRecord
*const rr
, mStatus
*status
);
137 extern mStatus
AddRRSetToVerifier(DNSSECVerifier
*dv
, const ResourceRecord
*const rr
, RRVerifier
*rv
, RRVerifierSet set
);
138 extern void VerifySignature(mDNS
*const m
, DNSSECVerifier
*dv
, DNSQuestion
*q
);
139 extern void FreeDNSSECVerifier(mDNS
*const m
, DNSSECVerifier
*dv
);
140 extern DNSSECVerifier
*AllocateDNSSECVerifier(mDNS
*const m
, const domainname
*name
, mDNSu16 rrtype
, mDNSInterfaceID InterfaceID
,
141 mDNSu8 ValidationRequired
, DNSSECVerifierCallback dvcallback
, mDNSQuestionCallback qcallback
);
142 extern void InitializeQuestion(mDNS
*const m
, DNSQuestion
*question
, mDNSInterfaceID InterfaceID
, const domainname
*qname
,
143 mDNSu16 qtype
, mDNSQuestionCallback
*callback
, void *context
);
144 extern void ValidateRRSIG(DNSSECVerifier
*dv
, RRVerifierSet type
, const ResourceRecord
*const rr
);
145 extern void AuthChainLink(DNSSECVerifier
*dv
, AuthChain
*ae
);
146 extern mStatus
DNSNameToLowerCase(domainname
*d
, domainname
*result
);
147 extern int DNSMemCmp(const mDNSu8
*const m1
, const mDNSu8
*const m2
, int len
);
148 extern int DNSSECCanonicalOrder(const domainname
*const d1
, const domainname
*const d2
, int *subdomain
);
149 extern void ProveInsecure(mDNS
*const m
, DNSSECVerifier
*dv
, InsecureContext
*ic
, domainname
*trigger
);
150 extern void BumpDNSSECStats(mDNS
*const m
, DNSSECStatsAction action
, DNSSECStatsType type
, mDNSu32 value
);
151 extern char *DNSSECStatusName(DNSSECStatus status
);
153 // DNSSECProbe belongs in DNSSECSupport.h but then we don't want to expose yet another plaform specific dnssec file
154 // to other platforms where dnssec is not supported.
155 extern void DNSSECProbe(mDNS
*const m
);