5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome/* -*- Mode: C; tab-width: 4 -*-
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome *
cda73f64f20b8a0afc4909f5ea1f055ec7913856Toomas Soome * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome *
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome * Licensed under the Apache License, Version 2.0 (the "License");
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome * you may not use this file except in compliance with the License.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome * You may obtain a copy of the License at
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome *
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome * http://www.apache.org/licenses/LICENSE-2.0
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome *
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome * Unless required by applicable law or agreed to in writing, software
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome * distributed under the License is distributed on an "AS IS" BASIS,
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome * See the License for the specific language governing permissions and
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome * limitations under the License.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome */
cda73f64f20b8a0afc4909f5ea1f055ec7913856Toomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#ifndef __DNSSEC_H
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define __DNSSEC_H
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#include "CryptoAlg.h"
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#include "mDNSDebug.h"
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soometypedef enum
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome{
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVS_rr, RRVS_rrsig, RRVS_key, RRVS_rrsig_key, RRVS_ds, RRVS_done,
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome} RRVerifierSet;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soometypedef struct RRVerifier_struct RRVerifier;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soometypedef struct DNSSECVerifier_struct DNSSECVerifier;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soometypedef struct AuthChain_struct AuthChain;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soometypedef struct InsecureContext_struct InsecureContext;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomestruct RRVerifier_struct
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome{
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *next;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu16 rrtype;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu16 rrclass;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu32 rroriginalttl;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu16 rdlength;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu16 found;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu32 namehash;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu32 rdatahash;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome domainname name;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu8 *rdata;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome};
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// Each AuthChain element has one rrset (with multiple resource records of same type), rrsig and key
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// that validates the rrset.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomestruct AuthChain_struct
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome{
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome AuthChain *next; // Next element in the chain
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *rrset; // RRSET that is authenticated
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *rrsig; // Signature for that RRSET
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *key; // Public key for that RRSET
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome};
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define ResetAuthChain(dv) { \
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome (dv)->ac = mDNSNULL; \
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome (dv)->actail = &((dv)->ac); \
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome}
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soometypedef void DNSSECVerifierCallback (mDNS *const m, DNSSECVerifier *dv, DNSSECStatus status);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome//
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// When we do a validation for a question, there might be additional validations that needs to be done e.g.,
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// wildcard expanded answer. It is also possible that in the case of nsec we need to prove both that a wildcard
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// does not apply and the closest encloser proves that name does not exist. We identify these with the following
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// flags.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome//
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// Note: In the following, by "marking the validation", we mean that as part of validation we need to prove
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// the ones that are marked with.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome//
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// A wildcard may be used to answer a question. In that case, we need to verify that the right wildcard was
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// used in answering the question. This is done by marking the validation with WILDCARD_PROVES_ANSWER_EXPANDED.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome//
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// Sometimes we get a NXDOMAIN response. In this case, we may have a wildcard where we need to prove
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// that the wildcard proves that the name does not exist. This is done by marking the validation with
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// WILDCARD_PROVES_NONAME_EXISTS.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome//
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// In the case of NODATA error, sometimes the name may exist but the query type does not exist. This is done by
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// marking the validation with NSEC_PROVES_NOTYPE_EXISTS.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome//
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// In both NXDOMAIN and NODATA proofs, we may have to prove that the NAME does not exist. This is done by marking
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// the validation with NSEC_PROVES_NONAME_EXISTS.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome//
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define WILDCARD_PROVES_ANSWER_EXPANDED 0x00000001
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define WILDCARD_PROVES_NONAME_EXISTS 0x00000002
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define NSEC_PROVES_NOTYPE_EXISTS 0x00000004
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define NSEC_PROVES_NONAME_EXISTS 0x00000008
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define NSEC3_OPT_OUT 0x00000010 // OptOut was set in NSEC3
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomestruct DNSSECVerifier_struct
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome{
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome domainname origName; // Original question name that needs verification
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu16 origType; // Original question type corresponding to origName
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu16 currQtype; // Current question type that is being verified
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSInterfaceID InterfaceID; // InterfaceID of the question
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome DNSQuestion q;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu8 recursed; // Number of times recursed during validation
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu8 ValidationRequired; // Copy of the question's ValidationRequired status
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu8 InsecureProofDone;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu8 NumPackets; // Number of packets that we send on the wire for DNSSEC verification.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSs32 StartTime; // Time the DNSSEC verification starts
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu32 flags;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifierSet next;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome domainname *wildcardName; // set if the answer is wildcard expanded
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *pendingNSEC;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome DNSSECVerifierCallback *DVCallback;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome DNSSECVerifier *parent;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *rrset; // rrset for which we have to verify
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *rrsig; // RRSIG for rrset
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *key; // DNSKEY for rrset
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *rrsigKey; // RRSIG for DNSKEY
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome RRVerifier *ds; // DS for DNSKEY set in parent zone
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome AuthChain *saveac;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome AuthChain *ac;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome AuthChain **actail;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome AlgContext *ctx;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome};
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomestruct InsecureContext_struct
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome{
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome DNSSECVerifier *dv; // dv for which we are doing the insecure proof
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu8 skip; // labels to skip for forming the name from origName
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome DNSSECStatus status; // status to deliver when done
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu8 triggerLabelCount; // Label count of the name that triggered the insecure proof
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome DNSQuestion q;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome};
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define LogDNSSEC LogOperation
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define DNS_SERIAL_GT(a, b) ((int)((a) - (b)) > 0)
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#define DNS_SERIAL_LT(a, b) ((int)((a) - (b)) < 0)
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern void StartDNSSECVerification(mDNS *const m, void *context);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern RRVerifier* AllocateRRVerifier(const ResourceRecord *const rr, mStatus *status);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern mStatus AddRRSetToVerifier(DNSSECVerifier *dv, const ResourceRecord *const rr, RRVerifier *rv, RRVerifierSet set);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern void VerifySignature(mDNS *const m, DNSSECVerifier *dv, DNSQuestion *q);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern void FreeDNSSECVerifier(mDNS *const m, DNSSECVerifier *dv);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern DNSSECVerifier *AllocateDNSSECVerifier(mDNS *const m, const domainname *name, mDNSu16 rrtype, mDNSInterfaceID InterfaceID,
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu8 ValidationRequired, DNSSECVerifierCallback dvcallback, mDNSQuestionCallback qcallback);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern void InitializeQuestion(mDNS *const m, DNSQuestion *question, mDNSInterfaceID InterfaceID, const domainname *qname,
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome mDNSu16 qtype, mDNSQuestionCallback *callback, void *context);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern void ValidateRRSIG(DNSSECVerifier *dv, RRVerifierSet type, const ResourceRecord *const rr);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern void AuthChainLink(DNSSECVerifier *dv, AuthChain *ae);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern mStatus DNSNameToLowerCase(domainname *d, domainname *result);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern int DNSMemCmp(const mDNSu8 *const m1, const mDNSu8 *const m2, int len);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern int DNSSECCanonicalOrder(const domainname *const d1, const domainname *const d2, int *subdomain);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern void ProveInsecure(mDNS *const m, DNSSECVerifier *dv, InsecureContext *ic, domainname *trigger);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern void BumpDNSSECStats(mDNS *const m, DNSSECStatsAction action, DNSSECStatsType type, mDNSu32 value);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern char *DNSSECStatusName(DNSSECStatus status);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// DNSSECProbe belongs in DNSSECSupport.h but then we don't want to expose yet another plaform specific dnssec file
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome// to other platforms where dnssec is not supported.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeextern void DNSSECProbe(mDNS *const m);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome#endif // __DNSSEC_H