Annotation of embedaddon/dnsmasq/src/dnssec.c, revision 1.1.1.4

1.1       misho       1: /* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com>
1.1.1.3   misho       2:            and Copyright (c) 2012-2020 Simon Kelley
1.1       misho       3: 
                      4:    This program is free software; you can redistribute it and/or modify
                      5:    it under the terms of the GNU General Public License as published by
                      6:    the Free Software Foundation; version 2 dated June, 1991, or
                      7:    (at your option) version 3 dated 29 June, 2007.
                      8: 
                      9:    This program is distributed in the hope that it will be useful,
                     10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12:    GNU General Public License for more details.
                     13: 
                     14:    You should have received a copy of the GNU General Public License
                     15:    along with this program.  If not, see <http://www.gnu.org/licenses/>.
                     16: */
                     17: 
                     18: #include "dnsmasq.h"
                     19: 
                     20: #ifdef HAVE_DNSSEC
                     21: 
                     22: #define SERIAL_UNDEF  -100
                     23: #define SERIAL_EQ        0
                     24: #define SERIAL_LT       -1
                     25: #define SERIAL_GT        1
                     26: 
                     27: /* Convert from presentation format to wire format, in place.
                     28:    Also map UC -> LC.
                     29:    Note that using extract_name to get presentation format
                     30:    then calling to_wire() removes compression and maps case,
                     31:    thus generating names in canonical form.
                     32:    Calling to_wire followed by from_wire is almost an identity,
                     33:    except that the UC remains mapped to LC. 
1.1.1.2   misho      34: 
                     35:    Note that both /000 and '.' are allowed within labels. These get
                     36:    represented in presentation format using NAME_ESCAPE as an escape
                     37:    character. In theory, if all the characters in a name were /000 or
                     38:    '.' or NAME_ESCAPE then all would have to be escaped, so the 
                     39:    presentation format would be twice as long as the spec (1024). 
1.1.1.3   misho      40:    The buffers are all declared as 2049 (allowing for the trailing zero) 
1.1.1.2   misho      41:    for this reason.
1.1       misho      42: */
                     43: static int to_wire(char *name)
                     44: {
1.1.1.2   misho      45:   unsigned char *l, *p, *q, term;
1.1       misho      46:   int len;
                     47: 
                     48:   for (l = (unsigned char*)name; *l != 0; l = p)
                     49:     {
                     50:       for (p = l; *p != '.' && *p != 0; p++)
                     51:        if (*p >= 'A' && *p <= 'Z')
                     52:          *p = *p - 'A' + 'a';
1.1.1.2   misho      53:        else if (*p == NAME_ESCAPE)
                     54:          {
                     55:            for (q = p; *q; q++)
                     56:              *q = *(q+1);
                     57:            (*p)--;
                     58:          }
1.1       misho      59:       term = *p;
                     60:       
                     61:       if ((len = p - l) != 0)
                     62:        memmove(l+1, l, len);
                     63:       *l = len;
                     64:       
                     65:       p++;
                     66:       
                     67:       if (term == 0)
                     68:        *p = 0;
                     69:     }
                     70:   
                     71:   return l + 1 - (unsigned char *)name;
                     72: }
                     73: 
                     74: /* Note: no compression  allowed in input. */
                     75: static void from_wire(char *name)
                     76: {
1.1.1.2   misho      77:   unsigned char *l, *p, *last;
1.1       misho      78:   int len;
1.1.1.2   misho      79:   
                     80:   for (last = (unsigned char *)name; *last != 0; last += *last+1);
                     81:   
1.1       misho      82:   for (l = (unsigned char *)name; *l != 0; l += len+1)
                     83:     {
                     84:       len = *l;
                     85:       memmove(l, l+1, len);
1.1.1.2   misho      86:       for (p = l; p < l + len; p++)
                     87:        if (*p == '.' || *p == 0 || *p == NAME_ESCAPE)
                     88:          {
                     89:            memmove(p+1, p, 1 + last - p);
                     90:            len++;
                     91:            *p++ = NAME_ESCAPE; 
                     92:            (*p)++;
                     93:          }
                     94:        
1.1       misho      95:       l[len] = '.';
                     96:     }
                     97: 
                     98:   if ((char *)l != name)
                     99:     *(l-1) = 0;
                    100: }
                    101: 
                    102: /* Input in presentation format */
                    103: static int count_labels(char *name)
                    104: {
                    105:   int i;
1.1.1.3   misho     106:   char *p;
                    107:   
1.1       misho     108:   if (*name == 0)
                    109:     return 0;
                    110: 
1.1.1.3   misho     111:   for (p = name, i = 0; *p; p++)
                    112:     if (*p == '.')
1.1       misho     113:       i++;
                    114: 
1.1.1.3   misho     115:   /* Don't count empty first label. */
                    116:   return *name == '.' ? i : i+1;
1.1       misho     117: }
                    118: 
                    119: /* Implement RFC1982 wrapped compare for 32-bit numbers */
1.1.1.2   misho     120: static int serial_compare_32(u32 s1, u32 s2)
1.1       misho     121: {
                    122:   if (s1 == s2)
                    123:     return SERIAL_EQ;
                    124: 
                    125:   if ((s1 < s2 && (s2 - s1) < (1UL<<31)) ||
                    126:       (s1 > s2 && (s1 - s2) > (1UL<<31)))
                    127:     return SERIAL_LT;
                    128:   if ((s1 < s2 && (s2 - s1) > (1UL<<31)) ||
                    129:       (s1 > s2 && (s1 - s2) < (1UL<<31)))
                    130:     return SERIAL_GT;
                    131:   return SERIAL_UNDEF;
                    132: }
                    133: 
1.1.1.2   misho     134: /* Called at startup. If the timestamp file is configured and exists, put its mtime on
                    135:    timestamp_time. If it doesn't exist, create it, and set the mtime to 1-1-2015.
                    136:    return -1 -> Cannot create file.
                    137:            0 -> not using timestamp, or timestamp exists and is in past.
                    138:            1 -> timestamp exists and is in future.
                    139: */
                    140: 
                    141: static time_t timestamp_time;
                    142: 
                    143: int setup_timestamp(void)
1.1       misho     144: {
1.1.1.2   misho     145:   struct stat statbuf;
                    146:   
                    147:   daemon->back_to_the_future = 0;
                    148:   
                    149:   if (!daemon->timestamp_file)
                    150:     return 0;
                    151:   
                    152:   if (stat(daemon->timestamp_file, &statbuf) != -1)
                    153:     {
                    154:       timestamp_time = statbuf.st_mtime;
                    155:     check_and_exit:
                    156:       if (difftime(timestamp_time, time(0)) <=  0)
                    157:        {
                    158:          /* time already OK, update timestamp, and do key checking from the start. */
1.1.1.3   misho     159:          if (utimes(daemon->timestamp_file, NULL) == -1)
1.1.1.2   misho     160:            my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
                    161:          daemon->back_to_the_future = 1;
                    162:          return 0;
                    163:        }
                    164:       return 1;
                    165:     }
                    166:   
                    167:   if (errno == ENOENT)
                    168:     {
                    169:       /* NB. for explanation of O_EXCL flag, see comment on pidfile in dnsmasq.c */ 
                    170:       int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK | O_EXCL, 0666);
                    171:       if (fd != -1)
                    172:        {
1.1.1.3   misho     173:          struct timeval tv[2];
1.1.1.2   misho     174: 
                    175:          close(fd);
                    176:          
1.1.1.3   misho     177:          timestamp_time = 1420070400; /* 1-1-2015 */
                    178:          tv[0].tv_sec = tv[1].tv_sec = timestamp_time;
                    179:          tv[0].tv_usec = tv[1].tv_usec = 0;
                    180:          if (utimes(daemon->timestamp_file, tv) == 0)
1.1.1.2   misho     181:            goto check_and_exit;
                    182:        }
                    183:     }
1.1       misho     184: 
1.1.1.2   misho     185:   return -1;
                    186: }
                    187: 
                    188: /* Check whether today/now is between date_start and date_end */
1.1.1.3   misho     189: static int is_check_date(unsigned long curtime)
1.1.1.2   misho     190: {
1.1       misho     191:   /* Checking timestamps may be temporarily disabled */
1.1.1.2   misho     192:     
                    193:   /* If the current time if _before_ the timestamp
                    194:      on our persistent timestamp file, then assume the
                    195:      time if not yet correct, and don't check the
                    196:      key timestamps. As soon as the current time is
                    197:      later then the timestamp, update the timestamp
                    198:      and start checking keys */
                    199:   if (daemon->timestamp_file)
                    200:     {
                    201:       if (daemon->back_to_the_future == 0 && difftime(timestamp_time, curtime) <= 0)
                    202:        {
1.1.1.3   misho     203:          if (utimes(daemon->timestamp_file, NULL) != 0)
1.1.1.2   misho     204:            my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
                    205:          
1.1.1.3   misho     206:          my_syslog(LOG_INFO, _("system time considered valid, now checking DNSSEC signature timestamps."));
1.1.1.2   misho     207:          daemon->back_to_the_future = 1;
1.1.1.3   misho     208:          daemon->dnssec_no_time_check = 0;
1.1.1.2   misho     209:          queue_event(EVENT_RELOAD); /* purge cache */
                    210:        } 
                    211: 
1.1.1.3   misho     212:       return daemon->back_to_the_future;
1.1.1.2   misho     213:     }
1.1.1.3   misho     214:   else
                    215:     return !daemon->dnssec_no_time_check;
                    216: }
                    217: 
                    218: /* Return bytes of canonicalised rrdata one by one.
                    219:    Init state->ip with the RR, and state->end with the end of same.
                    220:    Init state->op to NULL.
                    221:    Init state->desc to RR descriptor.
                    222:    Init state->buff with a MAXDNAME * 2 buffer.
                    223:    
                    224:    After each call which returns 1, state->op points to the next byte of data.
                    225:    On returning 0, the end has been reached.
                    226: */
                    227: struct rdata_state {
                    228:   u16 *desc;
                    229:   size_t c;
                    230:   unsigned char *end, *ip, *op;
                    231:   char *buff;
                    232: };
                    233: 
                    234: static int get_rdata(struct dns_header *header, size_t plen, struct rdata_state *state)
1.1       misho     235: {
1.1.1.3   misho     236:   int d;
1.1       misho     237:   
1.1.1.3   misho     238:   if (state->op && state->c != 1)
1.1.1.2   misho     239:     {
1.1.1.3   misho     240:       state->op++;
                    241:       state->c--;
                    242:       return 1;
1.1.1.2   misho     243:     }
1.1.1.3   misho     244: 
                    245:   while (1)
                    246:     {
                    247:       d = *(state->desc);
1.1       misho     248:       
1.1.1.3   misho     249:       if (d == (u16)-1)
1.1       misho     250:        {
1.1.1.3   misho     251:          /* all the bytes to the end. */
                    252:          if ((state->c = state->end - state->ip) != 0)
                    253:            {
                    254:              state->op = state->ip;
                    255:              state->ip = state->end;;
                    256:            }
                    257:          else
                    258:            return 0;
                    259:        }
                    260:       else
                    261:        {
                    262:          state->desc++;
                    263:          
                    264:          if (d == (u16)0)
                    265:            {
                    266:              /* domain-name, canonicalise */
                    267:              int len;
                    268:              
                    269:              if (!extract_name(header, plen, &state->ip, state->buff, 1, 0) ||
                    270:                  (len = to_wire(state->buff)) == 0)
                    271:                continue;
                    272:              
                    273:              state->c = len;
                    274:              state->op = (unsigned char *)state->buff;
                    275:            }
                    276:          else
                    277:            {
                    278:              /* plain data preceding a domain-name, don't run off the end of the data */
                    279:              if ((state->end - state->ip) < d)
                    280:                d = state->end - state->ip;
                    281:              
                    282:              if (d == 0)
                    283:                continue;
                    284:                  
                    285:              state->op = state->ip;
                    286:              state->c = d;
                    287:              state->ip += d;
                    288:            }
1.1       misho     289:        }
                    290:       
1.1.1.3   misho     291:       return 1;
1.1       misho     292:     }
                    293: }
                    294: 
1.1.1.3   misho     295: /* Bubble sort the RRset into the canonical order. */
1.1       misho     296: 
1.1.1.3   misho     297: static int sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int rrsetidx, 
                    298:                      unsigned char **rrset, char *buff1, char *buff2)
1.1       misho     299: {
1.1.1.3   misho     300:   int swap, i, j;
1.1       misho     301:   
                    302:   do
                    303:     {
                    304:       for (swap = 0, i = 0; i < rrsetidx-1; i++)
                    305:        {
1.1.1.3   misho     306:          int rdlen1, rdlen2;
                    307:          struct rdata_state state1, state2;
                    308:          
1.1       misho     309:          /* Note that these have been determined to be OK previously,
                    310:             so we don't need to check for NULL return here. */
1.1.1.3   misho     311:          state1.ip = skip_name(rrset[i], header, plen, 10);
                    312:          state2.ip = skip_name(rrset[i+1], header, plen, 10);
                    313:          state1.op = state2.op = NULL;
                    314:          state1.buff = buff1;
                    315:          state2.buff = buff2;
                    316:          state1.desc = state2.desc = rr_desc;
                    317:          
                    318:          state1.ip += 8; /* skip class, type, ttl */
                    319:          GETSHORT(rdlen1, state1.ip);
                    320:          if (!CHECK_LEN(header, state1.ip, plen, rdlen1))
                    321:            return rrsetidx; /* short packet */
                    322:          state1.end = state1.ip + rdlen1;
                    323:          
                    324:          state2.ip += 8; /* skip class, type, ttl */
                    325:          GETSHORT(rdlen2, state2.ip);
                    326:          if (!CHECK_LEN(header, state2.ip, plen, rdlen2))
                    327:            return rrsetidx; /* short packet */
                    328:          state2.end = state2.ip + rdlen2; 
                    329: 
                    330:          /* If the RR has no names in it then canonicalisation
                    331:             is the identity function and we can compare
                    332:             the RRs directly. If not we compare the 
                    333:             canonicalised RRs one byte at a time. */
                    334:          if (*rr_desc == (u16)-1)        
1.1       misho     335:            {
1.1.1.3   misho     336:              int rdmin = rdlen1 > rdlen2 ? rdlen2 : rdlen1;
                    337:              int cmp = memcmp(state1.ip, state2.ip, rdmin);
1.1       misho     338:              
1.1.1.3   misho     339:              if (cmp > 0 || (cmp == 0 && rdlen1 > rdmin))
1.1       misho     340:                {
                    341:                  unsigned char *tmp = rrset[i+1];
                    342:                  rrset[i+1] = rrset[i];
                    343:                  rrset[i] = tmp;
1.1.1.3   misho     344:                  swap = 1;
                    345:                }
                    346:              else if (cmp == 0 && (rdlen1 == rdlen2))
                    347:                {
                    348:                  /* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
                    349:                  for (j = i+1; j < rrsetidx-1; j++)
                    350:                    rrset[j] = rrset[j+1];
                    351:                  rrsetidx--;
                    352:                  i--;
1.1       misho     353:                }
                    354:            }
1.1.1.3   misho     355:          else
                    356:            /* Comparing canonicalised RRs, byte-at-a-time. */
                    357:            while (1)
                    358:              {
                    359:                int ok1, ok2;
                    360:                
                    361:                ok1 = get_rdata(header, plen, &state1);
                    362:                ok2 = get_rdata(header, plen, &state2);
                    363:                
                    364:                if (!ok1 && !ok2)
                    365:                  {
                    366:                    /* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
                    367:                    for (j = i+1; j < rrsetidx-1; j++)
                    368:                      rrset[j] = rrset[j+1];
                    369:                    rrsetidx--;
                    370:                    i--;
                    371:                    break;
                    372:                  }
                    373:                else if (ok1 && (!ok2 || *state1.op > *state2.op)) 
                    374:                  {
                    375:                    unsigned char *tmp = rrset[i+1];
                    376:                    rrset[i+1] = rrset[i];
                    377:                    rrset[i] = tmp;
                    378:                    swap = 1;
                    379:                    break;
                    380:                  }
                    381:                else if (ok2 && (!ok1 || *state2.op > *state1.op))
                    382:                  break;
                    383:                
                    384:                /* arrive here when bytes are equal, go round the loop again
                    385:                   and compare the next ones. */
                    386:              }
1.1       misho     387:        }
                    388:     } while (swap);
1.1.1.3   misho     389: 
                    390:   return rrsetidx;
1.1       misho     391: }
                    392: 
1.1.1.2   misho     393: static unsigned char **rrset = NULL, **sigs = NULL;
1.1       misho     394: 
1.1.1.3   misho     395: /* Get pointers to RRset members and signature(s) for same.
1.1.1.2   misho     396:    Check signatures, and return keyname associated in keyname. */
                    397: static int explore_rrset(struct dns_header *header, size_t plen, int class, int type, 
                    398:                         char *name, char *keyname, int *sigcnt, int *rrcnt)
1.1       misho     399: {
1.1.1.2   misho     400:   static int rrset_sz = 0, sig_sz = 0; 
1.1       misho     401:   unsigned char *p;
1.1.1.2   misho     402:   int rrsetidx, sigidx, j, rdlen, res;
                    403:   int gotkey = 0;
1.1       misho     404: 
                    405:   if (!(p = skip_questions(header, plen)))
1.1.1.3   misho     406:     return 0;
1.1       misho     407: 
1.1.1.2   misho     408:    /* look for RRSIGs for this RRset and get pointers to each RR in the set. */
1.1       misho     409:   for (rrsetidx = 0, sigidx = 0, j = ntohs(header->ancount) + ntohs(header->nscount); 
                    410:        j != 0; j--) 
                    411:     {
                    412:       unsigned char *pstart, *pdata;
1.1.1.2   misho     413:       int stype, sclass, type_covered;
1.1       misho     414: 
                    415:       pstart = p;
                    416:       
                    417:       if (!(res = extract_name(header, plen, &p, name, 0, 10)))
1.1.1.3   misho     418:        return 0; /* bad packet */
1.1       misho     419:       
                    420:       GETSHORT(stype, p);
                    421:       GETSHORT(sclass, p);
1.1.1.3   misho     422:            
1.1       misho     423:       pdata = p;
                    424: 
1.1.1.3   misho     425:       p += 4; /* TTL */
1.1       misho     426:       GETSHORT(rdlen, p);
                    427:       
                    428:       if (!CHECK_LEN(header, p, plen, rdlen))
1.1.1.2   misho     429:        return 0; 
1.1       misho     430:       
                    431:       if (res == 1 && sclass == class)
                    432:        {
                    433:          if (stype == type)
                    434:            {
                    435:              if (!expand_workspace(&rrset, &rrset_sz, rrsetidx))
1.1.1.2   misho     436:                return 0; 
1.1       misho     437:              
                    438:              rrset[rrsetidx++] = pstart;
                    439:            }
                    440:          
                    441:          if (stype == T_RRSIG)
                    442:            {
                    443:              if (rdlen < 18)
1.1.1.2   misho     444:                return 0; /* bad packet */ 
1.1       misho     445:              
                    446:              GETSHORT(type_covered, p);
1.1.1.2   misho     447:              p += 16; /* algo, labels, orig_ttl, sig_expiration, sig_inception, key_tag */
                    448:              
                    449:              if (gotkey)
                    450:                {
                    451:                  /* If there's more than one SIG, ensure they all have same keyname */
                    452:                  if (extract_name(header, plen, &p, keyname, 0, 0) != 1)
                    453:                    return 0;
                    454:                }
                    455:              else
                    456:                {
                    457:                  gotkey = 1;
                    458:                  
                    459:                  if (!extract_name(header, plen, &p, keyname, 1, 0))
                    460:                    return 0;
                    461:                  
                    462:                  /* RFC 4035 5.3.1 says that the Signer's Name field MUST equal
                    463:                     the name of the zone containing the RRset. We can't tell that
                    464:                     for certain, but we can check that  the RRset name is equal to
                    465:                     or encloses the signers name, which should be enough to stop 
                    466:                     an attacker using signatures made with the key of an unrelated 
                    467:                     zone he controls. Note that the root key is always allowed. */
                    468:                  if (*keyname != 0)
                    469:                    {
                    470:                      char *name_start;
                    471:                      for (name_start = name; !hostname_isequal(name_start, keyname); )
                    472:                        if ((name_start = strchr(name_start, '.')))
                    473:                          name_start++; /* chop a label off and try again */
                    474:                        else
                    475:                          return 0;
                    476:                    }
                    477:                }
                    478:                  
1.1       misho     479:              
                    480:              if (type_covered == type)
                    481:                {
                    482:                  if (!expand_workspace(&sigs, &sig_sz, sigidx))
1.1.1.2   misho     483:                    return 0; 
1.1       misho     484:                  
                    485:                  sigs[sigidx++] = pdata;
                    486:                } 
                    487:              
1.1.1.3   misho     488:              p = pdata + 6; /* restore for ADD_RDLEN */
1.1       misho     489:            }
                    490:        }
                    491:       
                    492:       if (!ADD_RDLEN(header, p, plen, rdlen))
1.1.1.2   misho     493:        return 0;
1.1       misho     494:     }
                    495:   
1.1.1.2   misho     496:   *sigcnt = sigidx;
                    497:   *rrcnt = rrsetidx;
                    498: 
                    499:   return 1;
                    500: }
                    501: 
                    502: /* Validate a single RRset (class, type, name) in the supplied DNS reply 
                    503:    Return code:
                    504:    STAT_SECURE   if it validates.
                    505:    STAT_SECURE_WILDCARD if it validates and is the result of wildcard expansion.
                    506:    (In this case *wildcard_out points to the "body" of the wildcard within name.) 
                    507:    STAT_BOGUS    signature is wrong, bad packet.
                    508:    STAT_NEED_KEY need DNSKEY to complete validation (name is returned in keyname)
                    509:    STAT_NEED_DS  need DS to complete validation (name is returned in keyname)
                    510: 
                    511:    If key is non-NULL, use that key, which has the algo and tag given in the params of those names,
                    512:    otherwise find the key in the cache.
                    513: 
                    514:    Name is unchanged on exit. keyname is used as workspace and trashed.
                    515: 
                    516:    Call explore_rrset first to find and count RRs and sigs.
1.1.1.3   misho     517: 
                    518:    ttl_out is the floor on TTL, based on TTL and orig_ttl and expiration of sig used to validate.
1.1.1.2   misho     519: */
                    520: static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class, int type, int sigidx, int rrsetidx, 
1.1.1.3   misho     521:                          char *name, char *keyname, char **wildcard_out, struct blockdata *key, int keylen,
                    522:                          int algo_in, int keytag_in, unsigned long *ttl_out)
1.1.1.2   misho     523: {
                    524:   unsigned char *p;
1.1.1.3   misho     525:   int rdlen, j, name_labels, algo, labels, key_tag;
1.1.1.2   misho     526:   struct crec *crecp = NULL;
                    527:   u16 *rr_desc = rrfilter_desc(type);
1.1.1.3   misho     528:   u32 sig_expiration, sig_inception;
1.1.1.4 ! misho     529:   int failflags = DNSSEC_FAIL_NOSIG | DNSSEC_FAIL_NYV | DNSSEC_FAIL_EXP | DNSSEC_FAIL_NOKEYSUP;
        !           530:   
1.1.1.3   misho     531:   unsigned long curtime = time(0);
                    532:   int time_check = is_check_date(curtime);
                    533:   
1.1.1.2   misho     534:   if (wildcard_out)
                    535:     *wildcard_out = NULL;
1.1       misho     536:   
1.1.1.2   misho     537:   name_labels = count_labels(name); /* For 4035 5.3.2 check */
                    538: 
1.1       misho     539:   /* Sort RRset records into canonical order. 
                    540:      Note that at this point keyname and daemon->workspacename buffs are
                    541:      unused, and used as workspace by the sort. */
1.1.1.3   misho     542:   rrsetidx = sort_rrset(header, plen, rr_desc, rrsetidx, rrset, daemon->workspacename, keyname);
1.1       misho     543:          
                    544:   /* Now try all the sigs to try and find one which validates */
                    545:   for (j = 0; j <sigidx; j++)
                    546:     {
                    547:       unsigned char *psav, *sig, *digest;
                    548:       int i, wire_len, sig_len;
                    549:       const struct nettle_hash *hash;
                    550:       void *ctx;
                    551:       char *name_start;
1.1.1.3   misho     552:       u32 nsigttl, ttl, orig_ttl;
1.1.1.4 ! misho     553: 
        !           554:       failflags &= ~DNSSEC_FAIL_NOSIG;
1.1       misho     555:       
                    556:       p = sigs[j];
1.1.1.3   misho     557:       GETLONG(ttl, p);
1.1       misho     558:       GETSHORT(rdlen, p); /* rdlen >= 18 checked previously */
                    559:       psav = p;
                    560:       
                    561:       p += 2; /* type_covered - already checked */
                    562:       algo = *p++;
                    563:       labels = *p++;
                    564:       GETLONG(orig_ttl, p);
                    565:       GETLONG(sig_expiration, p);
                    566:       GETLONG(sig_inception, p);
                    567:       GETSHORT(key_tag, p);
                    568:       
                    569:       if (!extract_name(header, plen, &p, keyname, 1, 0))
                    570:        return STAT_BOGUS;
                    571: 
1.1.1.4 ! misho     572:       if (!time_check)
        !           573:        failflags &= ~(DNSSEC_FAIL_NYV | DNSSEC_FAIL_EXP);
        !           574:       else
        !           575:        {
        !           576:          /* We must explicitly check against wanted values, because of SERIAL_UNDEF */
        !           577:          if (serial_compare_32(curtime, sig_inception) == SERIAL_LT)
        !           578:            continue;
        !           579:          else
        !           580:            failflags &= ~DNSSEC_FAIL_NYV;
        !           581:          
        !           582:          if (serial_compare_32(curtime, sig_expiration) == SERIAL_GT)
        !           583:            continue;
        !           584:          else
        !           585:            failflags &= ~DNSSEC_FAIL_EXP;
        !           586:        }
        !           587: 
        !           588:       if (!(hash = hash_find(algo_digest_name(algo))))
        !           589:        continue;
        !           590:       else
        !           591:        failflags &= ~DNSSEC_FAIL_NOKEYSUP;
        !           592:       
        !           593:       if (labels > name_labels ||
1.1       misho     594:          !hash_init(hash, &ctx, &digest))
                    595:        continue;
1.1.1.4 ! misho     596:       
1.1       misho     597:       /* OK, we have the signature record, see if the relevant DNSKEY is in the cache. */
                    598:       if (!key && !(crecp = cache_find_by_name(NULL, keyname, now, F_DNSKEY)))
                    599:        return STAT_NEED_KEY;
1.1.1.3   misho     600: 
                    601:        if (ttl_out)
                    602:         {
                    603:           /* 4035 5.3.3 rules on TTLs */
                    604:           if (orig_ttl < ttl)
                    605:             ttl = orig_ttl;
                    606:           
                    607:           if (time_check && difftime(sig_expiration, curtime) < ttl)
                    608:             ttl = difftime(sig_expiration, curtime);
                    609: 
                    610:           *ttl_out = ttl;
                    611:         }
                    612:        
1.1       misho     613:       sig = p;
                    614:       sig_len = rdlen - (p - psav);
                    615:               
                    616:       nsigttl = htonl(orig_ttl);
                    617:       
                    618:       hash->update(ctx, 18, psav);
                    619:       wire_len = to_wire(keyname);
                    620:       hash->update(ctx, (unsigned int)wire_len, (unsigned char*)keyname);
                    621:       from_wire(keyname);
1.1.1.3   misho     622: 
                    623: #define RRBUFLEN 128 /* Most RRs are smaller than this. */
1.1       misho     624:       
                    625:       for (i = 0; i < rrsetidx; ++i)
                    626:        {
1.1.1.3   misho     627:          int j;
                    628:          struct rdata_state state;
                    629:          u16 len;
                    630:          unsigned char rrbuf[RRBUFLEN];
1.1       misho     631:          
                    632:          p = rrset[i];
1.1.1.3   misho     633:          
1.1       misho     634:          if (!extract_name(header, plen, &p, name, 1, 10)) 
                    635:            return STAT_BOGUS;
                    636: 
                    637:          name_start = name;
                    638:          
                    639:          /* if more labels than in RRsig name, hash *.<no labels in rrsig labels field>  4035 5.3.2 */
                    640:          if (labels < name_labels)
                    641:            {
1.1.1.3   misho     642:              for (j = name_labels - labels; j != 0; j--)
1.1.1.2   misho     643:                {
                    644:                  while (*name_start != '.' && *name_start != 0)
                    645:                    name_start++;
1.1.1.3   misho     646:                  if (j != 1 && *name_start == '.')
1.1.1.2   misho     647:                    name_start++;
                    648:                }
                    649:              
                    650:              if (wildcard_out)
                    651:                *wildcard_out = name_start+1;
                    652: 
1.1       misho     653:              name_start--;
                    654:              *name_start = '*';
                    655:            }
                    656:          
                    657:          wire_len = to_wire(name_start);
                    658:          hash->update(ctx, (unsigned int)wire_len, (unsigned char *)name_start);
                    659:          hash->update(ctx, 4, p); /* class and type */
                    660:          hash->update(ctx, 4, (unsigned char *)&nsigttl);
1.1.1.3   misho     661: 
                    662:          p += 8; /* skip type, class, ttl */
1.1       misho     663:          GETSHORT(rdlen, p);
                    664:          if (!CHECK_LEN(header, p, plen, rdlen))
                    665:            return STAT_BOGUS; 
1.1.1.3   misho     666: 
                    667:          /* Optimisation for RR types which need no cannonicalisation.
                    668:             This includes DNSKEY DS NSEC and NSEC3, which are also long, so
                    669:             it saves lots of calls to get_rdata, and avoids the pessimal
                    670:             segmented insertion, even with a small rrbuf[].
                    671:             
                    672:             If canonicalisation is not needed, a simple insertion into the hash works.
                    673:          */
                    674:          if (*rr_desc == (u16)-1)
                    675:            {
                    676:              len = htons(rdlen);
                    677:              hash->update(ctx, 2, (unsigned char *)&len);
                    678:              hash->update(ctx, rdlen, p);
                    679:            }
                    680:          else
                    681:            {
                    682:              /* canonicalise rdata and calculate length of same, use 
                    683:                 name buffer as workspace for get_rdata. */
                    684:              state.ip = p;
                    685:              state.op = NULL;
                    686:              state.desc = rr_desc;
                    687:              state.buff = name;
                    688:              state.end = p + rdlen;
                    689:              
                    690:              for (j = 0; get_rdata(header, plen, &state); j++)
                    691:                if (j < RRBUFLEN)
                    692:                  rrbuf[j] = *state.op;
                    693:              
                    694:              len = htons((u16)j);
                    695:              hash->update(ctx, 2, (unsigned char *)&len); 
                    696:              
                    697:              /* If the RR is shorter than RRBUFLEN (most of them, in practice)
                    698:                 then we can just digest it now. If it exceeds RRBUFLEN we have to
                    699:                 go back to the start and do it in chunks. */
                    700:              if (j >= RRBUFLEN)
                    701:                {
                    702:                  state.ip = p;
                    703:                  state.op = NULL;
                    704:                  state.desc = rr_desc;
                    705:                  
                    706:                  for (j = 0; get_rdata(header, plen, &state); j++)
                    707:                    {
                    708:                      rrbuf[j] = *state.op;
                    709:                      
                    710:                      if (j == RRBUFLEN - 1)
                    711:                        {
                    712:                          hash->update(ctx, RRBUFLEN, rrbuf);
                    713:                          j = -1;
                    714:                        }
                    715:                    }
                    716:                }
                    717:              
                    718:              if (j != 0)
                    719:                hash->update(ctx, j, rrbuf);
                    720:            }
1.1       misho     721:        }
                    722:      
                    723:       hash->digest(ctx, hash->digest_size, digest);
                    724:       
                    725:       /* namebuff used for workspace above, restore to leave unchanged on exit */
                    726:       p = (unsigned char*)(rrset[0]);
1.1.1.4 ! misho     727:       if (!extract_name(header, plen, &p, name, 1, 0))
        !           728:        return STAT_BOGUS;
1.1       misho     729: 
                    730:       if (key)
                    731:        {
                    732:          if (algo_in == algo && keytag_in == key_tag &&
                    733:              verify(key, keylen, sig, sig_len, digest, hash->digest_size, algo))
                    734:            return STAT_SECURE;
                    735:        }
                    736:       else
                    737:        {
                    738:          /* iterate through all possible keys 4035 5.3.1 */
                    739:          for (; crecp; crecp = cache_find_by_name(crecp, keyname, now, F_DNSKEY))
                    740:            if (crecp->addr.key.algo == algo && 
                    741:                crecp->addr.key.keytag == key_tag &&
                    742:                crecp->uid == (unsigned int)class &&
                    743:                verify(crecp->addr.key.keydata, crecp->addr.key.keylen, sig, sig_len, digest, hash->digest_size, algo))
                    744:              return (labels < name_labels) ? STAT_SECURE_WILDCARD : STAT_SECURE;
                    745:        }
                    746:     }
                    747: 
1.1.1.4 ! misho     748:   /* If we reach this point, no verifying key was found */
        !           749:   return STAT_BOGUS | failflags | DNSSEC_FAIL_NOKEY;
1.1       misho     750: }
                    751:  
1.1.1.2   misho     752: 
1.1       misho     753: /* The DNS packet is expected to contain the answer to a DNSKEY query.
                    754:    Put all DNSKEYs in the answer which are valid into the cache.
                    755:    return codes:
1.1.1.2   misho     756:          STAT_OK        Done, key(s) in cache.
                    757:         STAT_BOGUS     No DNSKEYs found, which  can be validated with DS,
                    758:                        or self-sign for DNSKEY RRset is not valid, bad packet.
                    759:         STAT_NEED_DS   DS records to validate a key not found, name in keyname 
                    760:         STAT_NEED_KEY  DNSKEY records to validate a key not found, name in keyname 
1.1       misho     761: */
                    762: int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
                    763: {
                    764:   unsigned char *psave, *p = (unsigned char *)(header+1);
                    765:   struct crec *crecp, *recp1;
1.1.1.3   misho     766:   int rc, j, qtype, qclass, rdlen, flags, algo, valid, keytag;
                    767:   unsigned long ttl, sig_ttl;
1.1       misho     768:   struct blockdata *key;
1.1.1.3   misho     769:   union all_addr a;
1.1.1.4 ! misho     770:   int failflags = DNSSEC_FAIL_NOSIG | DNSSEC_FAIL_NODSSUP | DNSSEC_FAIL_NOZONE | DNSSEC_FAIL_NOKEY;
1.1       misho     771: 
                    772:   if (ntohs(header->qdcount) != 1 ||
1.1.1.3   misho     773:       RCODE(header) == SERVFAIL || RCODE(header) == REFUSED ||
1.1       misho     774:       !extract_name(header, plen, &p, name, 1, 4))
1.1.1.4 ! misho     775:     return STAT_BOGUS | DNSSEC_FAIL_NOKEY;
1.1       misho     776: 
                    777:   GETSHORT(qtype, p);
                    778:   GETSHORT(qclass, p);
                    779:   
1.1.1.2   misho     780:   if (qtype != T_DNSKEY || qclass != class || ntohs(header->ancount) == 0)
1.1.1.4 ! misho     781:     return STAT_BOGUS | DNSSEC_FAIL_NOKEY;
1.1       misho     782: 
                    783:   /* See if we have cached a DS record which validates this key */
                    784:   if (!(crecp = cache_find_by_name(NULL, name, now, F_DS)))
                    785:     {
                    786:       strcpy(keyname, name);
                    787:       return STAT_NEED_DS;
                    788:     }
                    789:   
                    790:   /* NOTE, we need to find ONE DNSKEY which matches the DS */
                    791:   for (valid = 0, j = ntohs(header->ancount); j != 0 && !valid; j--) 
                    792:     {
                    793:       /* Ensure we have type, class  TTL and length */
                    794:       if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
                    795:        return STAT_BOGUS; /* bad packet */
                    796:   
                    797:       GETSHORT(qtype, p); 
                    798:       GETSHORT(qclass, p);
                    799:       GETLONG(ttl, p);
                    800:       GETSHORT(rdlen, p);
                    801:  
                    802:       if (!CHECK_LEN(header, p, plen, rdlen) || rdlen < 4)
                    803:        return STAT_BOGUS; /* bad packet */
                    804:       
                    805:       if (qclass != class || qtype != T_DNSKEY || rc == 2)
                    806:        {
                    807:          p += rdlen;
                    808:          continue;
                    809:        }
                    810:             
                    811:       psave = p;
                    812:       
                    813:       GETSHORT(flags, p);
                    814:       if (*p++ != 3)
1.1.1.4 ! misho     815:        return STAT_BOGUS | DNSSEC_FAIL_NOKEY;
1.1       misho     816:       algo = *p++;
                    817:       keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
                    818:       key = NULL;
                    819:       
                    820:       /* key must have zone key flag set */
                    821:       if (flags & 0x100)
1.1.1.4 ! misho     822:        {
        !           823:          key = blockdata_alloc((char*)p, rdlen - 4);
        !           824:          failflags &= ~DNSSEC_FAIL_NOZONE;
        !           825:        }
1.1       misho     826:       
                    827:       p = psave;
                    828:       
                    829:       if (!ADD_RDLEN(header, p, plen, rdlen))
                    830:        {
                    831:          if (key)
                    832:            blockdata_free(key);
                    833:          return STAT_BOGUS; /* bad packet */
                    834:        }
                    835: 
                    836:       /* No zone key flag or malloc failure */
                    837:       if (!key)
                    838:        continue;
                    839:       
                    840:       for (recp1 = crecp; recp1; recp1 = cache_find_by_name(recp1, name, now, F_DS))
                    841:        {
                    842:          void *ctx;
                    843:          unsigned char *digest, *ds_digest;
                    844:          const struct nettle_hash *hash;
1.1.1.2   misho     845:          int sigcnt, rrcnt;
1.1.1.4 ! misho     846:          int wire_len;
        !           847:          
1.1       misho     848:          if (recp1->addr.ds.algo == algo && 
                    849:              recp1->addr.ds.keytag == keytag &&
1.1.1.4 ! misho     850:              recp1->uid == (unsigned int)class)
1.1       misho     851:            {
1.1.1.4 ! misho     852:              failflags &= ~DNSSEC_FAIL_NOKEY;
        !           853:              
        !           854:              if (!(hash = hash_find(ds_digest_name(recp1->addr.ds.digest))))
        !           855:                continue;
        !           856:              else
        !           857:                failflags &= ~DNSSEC_FAIL_NODSSUP;
        !           858: 
        !           859:              if (!hash_init(hash, &ctx, &digest))
        !           860:                continue;
        !           861:              
        !           862:              wire_len = to_wire(name);
1.1       misho     863:              
                    864:              /* Note that digest may be different between DSs, so 
                    865:                 we can't move this outside the loop. */
                    866:              hash->update(ctx, (unsigned int)wire_len, (unsigned char *)name);
                    867:              hash->update(ctx, (unsigned int)rdlen, psave);
                    868:              hash->digest(ctx, hash->digest_size, digest);
                    869:              
                    870:              from_wire(name);
                    871:              
1.1.1.2   misho     872:              if (!(recp1->flags & F_NEG) &&
                    873:                  recp1->addr.ds.keylen == (int)hash->digest_size &&
1.1.1.3   misho     874:                  (ds_digest = blockdata_retrieve(recp1->addr.ds.keydata, recp1->addr.ds.keylen, NULL)) &&
1.1       misho     875:                  memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 &&
1.1.1.2   misho     876:                  explore_rrset(header, plen, class, T_DNSKEY, name, keyname, &sigcnt, &rrcnt) &&
1.1.1.4 ! misho     877:                  rrcnt != 0)
1.1       misho     878:                {
1.1.1.4 ! misho     879:                  if (sigcnt == 0)
        !           880:                    continue;
        !           881:                  else
        !           882:                    failflags &= ~DNSSEC_FAIL_NOSIG;
        !           883:                  
        !           884:                  rc = validate_rrset(now, header, plen, class, T_DNSKEY, sigcnt, rrcnt, name, keyname, 
        !           885:                                      NULL, key, rdlen - 4, algo, keytag, &sig_ttl);
        !           886: 
        !           887:                  failflags &= rc;
        !           888:                  
        !           889:                  if (STAT_ISEQUAL(rc, STAT_SECURE))
        !           890:                    {
        !           891:                      valid = 1;
        !           892:                      break;
        !           893:                    }
1.1       misho     894:                }
                    895:            }
                    896:        }
                    897:       blockdata_free(key);
                    898:     }
                    899: 
                    900:   if (valid)
                    901:     {
1.1.1.2   misho     902:       /* DNSKEY RRset determined to be OK, now cache it. */
1.1       misho     903:       cache_start_insert();
                    904:       
                    905:       p = skip_questions(header, plen);
                    906: 
                    907:       for (j = ntohs(header->ancount); j != 0; j--) 
                    908:        {
                    909:          /* Ensure we have type, class  TTL and length */
                    910:          if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
1.1.1.2   misho     911:            return STAT_BOGUS; /* bad packet */
1.1       misho     912:          
                    913:          GETSHORT(qtype, p); 
                    914:          GETSHORT(qclass, p);
                    915:          GETLONG(ttl, p);
                    916:          GETSHORT(rdlen, p);
1.1.1.3   misho     917: 
                    918:          /* TTL may be limited by sig. */
                    919:          if (sig_ttl < ttl)
                    920:            ttl = sig_ttl;
1.1       misho     921:            
                    922:          if (!CHECK_LEN(header, p, plen, rdlen))
                    923:            return STAT_BOGUS; /* bad packet */
                    924:          
                    925:          if (qclass == class && rc == 1)
                    926:            {
                    927:              psave = p;
                    928:              
                    929:              if (qtype == T_DNSKEY)
                    930:                {
                    931:                  if (rdlen < 4)
                    932:                    return STAT_BOGUS; /* bad packet */
                    933:                  
                    934:                  GETSHORT(flags, p);
                    935:                  if (*p++ != 3)
                    936:                    return STAT_BOGUS;
                    937:                  algo = *p++;
                    938:                  keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
                    939:                  
                    940:                  if ((key = blockdata_alloc((char*)p, rdlen - 4)))
                    941:                    {
1.1.1.3   misho     942:                      a.key.keylen = rdlen - 4;
                    943:                      a.key.keydata = key;
                    944:                      a.key.algo = algo;
                    945:                      a.key.keytag = keytag;
                    946:                      a.key.flags = flags;
                    947:                      
                    948:                      if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK))
1.1.1.2   misho     949:                        {
                    950:                          blockdata_free(key);
                    951:                          return STAT_BOGUS;
                    952:                        }
1.1       misho     953:                      else
                    954:                        {
1.1.1.3   misho     955:                          a.log.keytag = keytag;
                    956:                          a.log.algo = algo;
                    957:                          if (algo_digest_name(algo))
1.1.1.4 ! misho     958:                            log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu", 0);
1.1.1.2   misho     959:                          else
1.1.1.4 ! misho     960:                            log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu (not supported)", 0);
1.1       misho     961:                        }
                    962:                    }
                    963:                }
1.1.1.2   misho     964:                      
1.1       misho     965:              p = psave;
                    966:            }
                    967: 
                    968:          if (!ADD_RDLEN(header, p, plen, rdlen))
                    969:            return STAT_BOGUS; /* bad packet */
                    970:        }
                    971:       
                    972:       /* commit cache insert. */
                    973:       cache_end_insert();
1.1.1.2   misho     974:       return STAT_OK;
1.1       misho     975:     }
                    976: 
1.1.1.4 ! misho     977:   log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DNSKEY", 0);
        !           978:   return STAT_BOGUS | failflags;
1.1       misho     979: }
                    980: 
                    981: /* The DNS packet is expected to contain the answer to a DS query
1.1.1.4 ! misho     982:    Put all DSs in the answer which are valid and have hash and signature algos
        !           983:    we support into the cache.
1.1.1.2   misho     984:    Also handles replies which prove that there's no DS at this location, 
                    985:    either because the zone is unsigned or this isn't a zone cut. These are
                    986:    cached too.
1.1.1.4 ! misho     987:    If none of the DS's are for supported algos, treat the answer as if 
        !           988:    it's a proof of no DS at this location. RFC4035 para 5.2.
1.1       misho     989:    return codes:
1.1.1.2   misho     990:    STAT_OK          At least one valid DS found and in cache.
                    991:    STAT_BOGUS       no DS in reply or not signed, fails validation, bad packet.
                    992:    STAT_NEED_KEY    DNSKEY records to validate a DS not found, name in keyname
                    993:    STAT_NEED_DS     DS record needed.
1.1       misho     994: */
                    995: 
                    996: int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
                    997: {
                    998:   unsigned char *p = (unsigned char *)(header+1);
1.1.1.4 ! misho     999:   int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0, found_supported = 0;
        !          1000:   int aclass, atype, rdlen, flags;
1.1.1.2   misho    1001:   unsigned long ttl;
1.1.1.3   misho    1002:   union all_addr a;
1.1       misho    1003: 
                   1004:   if (ntohs(header->qdcount) != 1 ||
                   1005:       !(p = skip_name(p, header, plen, 4)))
                   1006:     return STAT_BOGUS;
                   1007:   
                   1008:   GETSHORT(qtype, p);
                   1009:   GETSHORT(qclass, p);
                   1010: 
                   1011:   if (qtype != T_DS || qclass != class)
1.1.1.2   misho    1012:     rc = STAT_BOGUS;
1.1       misho    1013:   else
1.1.1.3   misho    1014:     rc = dnssec_validate_reply(now, header, plen, name, keyname, NULL, 0, &neganswer, &nons, &neg_ttl);
1.1       misho    1015:   
1.1.1.4 ! misho    1016:   if (STAT_ISEQUAL(rc, STAT_INSECURE))
1.1.1.3   misho    1017:     {
                   1018:       my_syslog(LOG_WARNING, _("Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"), name);
1.1.1.4 ! misho    1019:       log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS - not secure", 0);
        !          1020:       return STAT_BOGUS | DNSSEC_FAIL_INDET;
1.1.1.3   misho    1021:     }
                   1022:   
1.1       misho    1023:   p = (unsigned char *)(header+1);
1.1.1.4 ! misho    1024:   if (!extract_name(header, plen, &p, name, 1, 4))
        !          1025:       return STAT_BOGUS;
        !          1026: 
1.1       misho    1027:   p += 4; /* qtype, qclass */
                   1028:   
1.1.1.2   misho    1029:   /* If the key needed to validate the DS is on the same domain as the DS, we'll
                   1030:      loop getting nowhere. Stop that now. This can happen of the DS answer comes
                   1031:      from the DS's zone, and not the parent zone. */
1.1.1.4 ! misho    1032:   if (STAT_ISEQUAL(rc, STAT_NEED_KEY) && hostname_isequal(name, keyname))
1.1.1.2   misho    1033:     {
1.1.1.4 ! misho    1034:       log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS", 0);
1.1.1.2   misho    1035:       return STAT_BOGUS;
                   1036:     }
1.1       misho    1037:   
1.1.1.4 ! misho    1038:   if (!STAT_ISEQUAL(rc, STAT_SECURE))
1.1.1.2   misho    1039:     return rc;
                   1040:    
                   1041:   if (!neganswer)
1.1       misho    1042:     {
1.1.1.2   misho    1043:       cache_start_insert();
                   1044:       
                   1045:       for (i = 0; i < ntohs(header->ancount); i++)
                   1046:        {
                   1047:          if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
                   1048:            return STAT_BOGUS; /* bad packet */
                   1049:          
                   1050:          GETSHORT(atype, p);
                   1051:          GETSHORT(aclass, p);
                   1052:          GETLONG(ttl, p);
                   1053:          GETSHORT(rdlen, p);
                   1054:          
                   1055:          if (!CHECK_LEN(header, p, plen, rdlen))
                   1056:            return STAT_BOGUS; /* bad packet */
                   1057:          
                   1058:          if (aclass == class && atype == T_DS && rc == 1)
                   1059:            { 
                   1060:              int algo, digest, keytag;
                   1061:              unsigned char *psave = p;
                   1062:              struct blockdata *key;
1.1.1.3   misho    1063:           
1.1.1.2   misho    1064:              if (rdlen < 4)
                   1065:                return STAT_BOGUS; /* bad packet */
                   1066:              
                   1067:              GETSHORT(keytag, p);
                   1068:              algo = *p++;
                   1069:              digest = *p++;
                   1070:              
1.1.1.4 ! misho    1071:              if (!ds_digest_name(digest) || !algo_digest_name(algo))
        !          1072:                {
        !          1073:                  a.log.keytag = keytag;
        !          1074:                  a.log.algo = algo;
        !          1075:                  a.log.digest = digest;
        !          1076:                  log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)", 0);
        !          1077:                  neg_ttl = ttl;
        !          1078:                } 
        !          1079:              else if ((key = blockdata_alloc((char*)p, rdlen - 4)))
1.1.1.2   misho    1080:                {
1.1.1.3   misho    1081:                  a.ds.digest = digest;
                   1082:                  a.ds.keydata = key;
                   1083:                  a.ds.algo = algo;
                   1084:                  a.ds.keytag = keytag;
                   1085:                  a.ds.keylen = rdlen - 4;
1.1.1.4 ! misho    1086:                  
1.1.1.3   misho    1087:                  if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK))
1.1.1.2   misho    1088:                    {
                   1089:                      blockdata_free(key);
                   1090:                      return STAT_BOGUS;
                   1091:                    }
                   1092:                  else
                   1093:                    {
1.1.1.3   misho    1094:                      a.log.keytag = keytag;
                   1095:                      a.log.algo = algo;
                   1096:                      a.log.digest = digest;
1.1.1.4 ! misho    1097:                      log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu", 0);
        !          1098:                      found_supported = 1;
1.1.1.2   misho    1099:                    } 
                   1100:                }
                   1101:              
                   1102:              p = psave;
                   1103:            }
1.1.1.4 ! misho    1104: 
1.1.1.2   misho    1105:          if (!ADD_RDLEN(header, p, plen, rdlen))
                   1106:            return STAT_BOGUS; /* bad packet */
                   1107:        }
1.1       misho    1108: 
1.1.1.2   misho    1109:       cache_end_insert();
                   1110: 
1.1.1.4 ! misho    1111:       /* Fall through if no supported algo DS found. */
        !          1112:       if (found_supported)
        !          1113:        return STAT_OK;
1.1.1.2   misho    1114:     }
1.1.1.4 ! misho    1115:   
        !          1116:   flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK;
        !          1117:   
        !          1118:   if (neganswer)
1.1.1.2   misho    1119:     {
1.1       misho    1120:       if (RCODE(header) == NXDOMAIN)
                   1121:        flags |= F_NXDOMAIN;
                   1122:       
1.1.1.2   misho    1123:       /* We only cache validated DS records, DNSSECOK flag hijacked 
                   1124:         to store presence/absence of NS. */
                   1125:       if (nons)
                   1126:        flags &= ~F_DNSSECOK;
1.1       misho    1127:     }
1.1.1.4 ! misho    1128:   
        !          1129:   cache_start_insert();
        !          1130:   
        !          1131:   /* Use TTL from NSEC for negative cache entries */
        !          1132:   if (!cache_insert(name, NULL, class, now, neg_ttl, flags))
        !          1133:     return STAT_BOGUS;
        !          1134:   
        !          1135:   cache_end_insert();  
        !          1136:   
        !          1137:   if (neganswer)
        !          1138:     log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS", 0);
1.1.1.2   misho    1139:       
                   1140:   return STAT_OK;
1.1       misho    1141: }
                   1142: 
1.1.1.2   misho    1143: 
1.1       misho    1144: /* 4034 6.1 */
                   1145: static int hostname_cmp(const char *a, const char *b)
                   1146: {
                   1147:   char *sa, *ea, *ca, *sb, *eb, *cb;
                   1148:   unsigned char ac, bc;
                   1149:   
                   1150:   sa = ea = (char *)a + strlen(a);
                   1151:   sb = eb = (char *)b + strlen(b);
                   1152:  
                   1153:   while (1)
                   1154:     {
                   1155:       while (sa != a && *(sa-1) != '.')
                   1156:        sa--;
                   1157:       
                   1158:       while (sb != b && *(sb-1) != '.')
                   1159:        sb--;
                   1160: 
                   1161:       ca = sa;
                   1162:       cb = sb;
                   1163: 
                   1164:       while (1) 
                   1165:        {
                   1166:          if (ca == ea)
                   1167:            {
                   1168:              if (cb == eb)
                   1169:                break;
                   1170:              
                   1171:              return -1;
                   1172:            }
                   1173:          
                   1174:          if (cb == eb)
                   1175:            return 1;
                   1176:          
                   1177:          ac = (unsigned char) *ca++;
                   1178:          bc = (unsigned char) *cb++;
                   1179:          
                   1180:          if (ac >= 'A' && ac <= 'Z')
                   1181:            ac += 'a' - 'A';
                   1182:          if (bc >= 'A' && bc <= 'Z')
                   1183:            bc += 'a' - 'A';
                   1184:          
                   1185:          if (ac < bc)
                   1186:            return -1;
                   1187:          else if (ac != bc)
                   1188:            return 1;
                   1189:        }
                   1190: 
                   1191:      
                   1192:       if (sa == a)
                   1193:        {
                   1194:          if (sb == b)
                   1195:            return 0;
                   1196:          
                   1197:          return -1;
                   1198:        }
                   1199:       
                   1200:       if (sb == b)
                   1201:        return 1;
                   1202:       
1.1.1.2   misho    1203:       ea = --sa;
                   1204:       eb = --sb;
1.1       misho    1205:     }
                   1206: }
                   1207: 
1.1.1.3   misho    1208: static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsigned char **nsecs, unsigned char **labels, int nsec_count,
                   1209:                                    char *workspace1_in, char *workspace2, char *name, int type, int *nons)
1.1       misho    1210: {
                   1211:   int i, rc, rdlen;
                   1212:   unsigned char *p, *psave;
                   1213:   int offset = (type & 0xff) >> 3;
                   1214:   int mask = 0x80 >> (type & 0x07);
1.1.1.2   misho    1215: 
                   1216:   if (nons)
                   1217:     *nons = 1;
1.1       misho    1218:   
                   1219:   /* Find NSEC record that proves name doesn't exist */
                   1220:   for (i = 0; i < nsec_count; i++)
                   1221:     {
1.1.1.3   misho    1222:       char *workspace1 = workspace1_in;
                   1223:       int sig_labels, name_labels;
                   1224: 
1.1       misho    1225:       p = nsecs[i];
                   1226:       if (!extract_name(header, plen, &p, workspace1, 1, 10))
1.1.1.2   misho    1227:        return 0;
1.1       misho    1228:       p += 8; /* class, type, TTL */
                   1229:       GETSHORT(rdlen, p);
                   1230:       psave = p;
                   1231:       if (!extract_name(header, plen, &p, workspace2, 1, 10))
1.1.1.2   misho    1232:        return 0;
1.1.1.3   misho    1233: 
                   1234:       /* If NSEC comes from wildcard expansion, use original wildcard
                   1235:         as name for computation. */
                   1236:       sig_labels = *labels[i];
                   1237:       name_labels = count_labels(workspace1);
                   1238: 
                   1239:       if (sig_labels < name_labels)
                   1240:        {
                   1241:          int k;
                   1242:          for (k = name_labels - sig_labels; k != 0; k--)
                   1243:            {
                   1244:              while (*workspace1 != '.' && *workspace1 != 0)
                   1245:                workspace1++;
                   1246:              if (k != 1 && *workspace1 == '.')
                   1247:                workspace1++;
                   1248:            }
                   1249:          
                   1250:          workspace1--;
                   1251:          *workspace1 = '*';
                   1252:        }
                   1253:          
1.1       misho    1254:       rc = hostname_cmp(workspace1, name);
                   1255:       
                   1256:       if (rc == 0)
                   1257:        {
                   1258:          /* 4035 para 5.4. Last sentence */
                   1259:          if (type == T_NSEC || type == T_RRSIG)
1.1.1.2   misho    1260:            return 1;
1.1       misho    1261: 
                   1262:          /* NSEC with the same name as the RR we're testing, check
                   1263:             that the type in question doesn't appear in the type map */
                   1264:          rdlen -= p - psave;
                   1265:          /* rdlen is now length of type map, and p points to it */
                   1266:          
1.1.1.2   misho    1267:          /* If we can prove that there's no NS record, return that information. */
                   1268:          if (nons && rdlen >= 2 && p[0] == 0 && (p[2] & (0x80 >> T_NS)) != 0)
                   1269:            *nons = 0;
                   1270:          
                   1271:          if (rdlen >= 2 && p[0] == 0)
                   1272:            {
                   1273:              /* A CNAME answer would also be valid, so if there's a CNAME is should 
                   1274:                 have been returned. */
                   1275:              if ((p[2] & (0x80 >> T_CNAME)) != 0)
                   1276:                return 0;
                   1277:              
                   1278:              /* If the SOA bit is set for a DS record, then we have the
1.1.1.3   misho    1279:                 DS from the wrong side of the delegation. For the root DS, 
                   1280:                 this is expected. */
                   1281:              if (name_labels != 0 && type == T_DS && (p[2] & (0x80 >> T_SOA)) != 0)
1.1.1.2   misho    1282:                return 0;
                   1283:            }
                   1284: 
1.1       misho    1285:          while (rdlen >= 2)
                   1286:            {
                   1287:              if (!CHECK_LEN(header, p, plen, rdlen))
1.1.1.2   misho    1288:                return 0;
1.1       misho    1289:              
                   1290:              if (p[0] == type >> 8)
                   1291:                {
                   1292:                  /* Does the NSEC say our type exists? */
                   1293:                  if (offset < p[1] && (p[offset+2] & mask) != 0)
1.1.1.2   misho    1294:                    return 0;
1.1       misho    1295:                  
1.1.1.3   misho    1296:                  break; /* finished checking */
1.1       misho    1297:                }
                   1298:              
                   1299:              rdlen -= p[1];
                   1300:              p +=  p[1];
                   1301:            }
                   1302:          
1.1.1.2   misho    1303:          return 1;
1.1       misho    1304:        }
                   1305:       else if (rc == -1)
                   1306:        {
                   1307:          /* Normal case, name falls between NSEC name and next domain name,
                   1308:             wrap around case, name falls between NSEC name (rc == -1) and end */
1.1.1.2   misho    1309:          if (hostname_cmp(workspace2, name) >= 0 || hostname_cmp(workspace1, workspace2) >= 0)
                   1310:            return 1;
1.1       misho    1311:        }
                   1312:       else 
                   1313:        {
                   1314:          /* wrap around case, name falls between start and next domain name */
1.1.1.2   misho    1315:          if (hostname_cmp(workspace1, workspace2) >= 0 && hostname_cmp(workspace2, name) >=0 )
                   1316:            return 1;
1.1       misho    1317:        }
                   1318:     }
                   1319:   
1.1.1.2   misho    1320:   return 0;
1.1       misho    1321: }
                   1322: 
                   1323: /* return digest length, or zero on error */
                   1324: static int hash_name(char *in, unsigned char **out, struct nettle_hash const *hash, 
                   1325:                     unsigned char *salt, int salt_len, int iterations)
                   1326: {
                   1327:   void *ctx;
                   1328:   unsigned char *digest;
                   1329:   int i;
                   1330: 
                   1331:   if (!hash_init(hash, &ctx, &digest))
                   1332:     return 0;
                   1333:  
                   1334:   hash->update(ctx, to_wire(in), (unsigned char *)in);
                   1335:   hash->update(ctx, salt_len, salt);
                   1336:   hash->digest(ctx, hash->digest_size, digest);
                   1337: 
                   1338:   for(i = 0; i < iterations; i++)
                   1339:     {
                   1340:       hash->update(ctx, hash->digest_size, digest);
                   1341:       hash->update(ctx, salt_len, salt);
                   1342:       hash->digest(ctx, hash->digest_size, digest);
                   1343:     }
                   1344:    
                   1345:   from_wire(in);
                   1346: 
                   1347:   *out = digest;
                   1348:   return hash->digest_size;
                   1349: }
                   1350: 
                   1351: /* Decode base32 to first "." or end of string */
                   1352: static int base32_decode(char *in, unsigned char *out)
                   1353: {
                   1354:   int oc, on, c, mask, i;
                   1355:   unsigned char *p = out;
                   1356:  
                   1357:   for (c = *in, oc = 0, on = 0; c != 0 && c != '.'; c = *++in) 
                   1358:     {
                   1359:       if (c >= '0' && c <= '9')
                   1360:        c -= '0';
                   1361:       else if (c >= 'a' && c <= 'v')
                   1362:        c -= 'a', c += 10;
                   1363:       else if (c >= 'A' && c <= 'V')
                   1364:        c -= 'A', c += 10;
                   1365:       else
                   1366:        return 0;
                   1367:       
                   1368:       for (mask = 0x10, i = 0; i < 5; i++)
                   1369:         {
                   1370:          if (c & mask)
                   1371:            oc |= 1;
                   1372:          mask = mask >> 1;
                   1373:          if (((++on) & 7) == 0)
                   1374:            *p++ = oc;
                   1375:          oc = oc << 1;
                   1376:        }
                   1377:     }
                   1378:   
                   1379:   if ((on & 7) != 0)
                   1380:     return 0;
                   1381: 
                   1382:   return p - out;
                   1383: }
                   1384: 
1.1.1.2   misho    1385: static int check_nsec3_coverage(struct dns_header *header, size_t plen, int digest_len, unsigned char *digest, int type,
1.1.1.3   misho    1386:                                char *workspace1, char *workspace2, unsigned char **nsecs, int nsec_count, int *nons, int name_labels)
1.1.1.2   misho    1387: {
                   1388:   int i, hash_len, salt_len, base32_len, rdlen, flags;
                   1389:   unsigned char *p, *psave;
                   1390: 
                   1391:   for (i = 0; i < nsec_count; i++)
                   1392:     if ((p = nsecs[i]))
                   1393:       {
                   1394:                if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
                   1395:            !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
                   1396:          return 0;
                   1397:        
                   1398:        p += 8; /* class, type, TTL */
                   1399:        GETSHORT(rdlen, p);
                   1400:        psave = p;
                   1401:        p++; /* algo */
                   1402:        flags = *p++; /* flags */
                   1403:        p += 2; /* iterations */
                   1404:        salt_len = *p++; /* salt_len */
                   1405:        p += salt_len; /* salt */
                   1406:        hash_len = *p++; /* p now points to next hashed name */
                   1407:        
                   1408:        if (!CHECK_LEN(header, p, plen, hash_len))
                   1409:          return 0;
                   1410:        
                   1411:        if (digest_len == base32_len && hash_len == base32_len)
                   1412:          {
                   1413:            int rc = memcmp(workspace2, digest, digest_len);
                   1414: 
                   1415:            if (rc == 0)
                   1416:              {
                   1417:                /* We found an NSEC3 whose hashed name exactly matches the query, so
                   1418:                   we just need to check the type map. p points to the RR data for the record. */
                   1419:                
                   1420:                int offset = (type & 0xff) >> 3;
                   1421:                int mask = 0x80 >> (type & 0x07);
                   1422:                
                   1423:                p += hash_len; /* skip next-domain hash */
                   1424:                rdlen -= p - psave;
                   1425: 
                   1426:                if (!CHECK_LEN(header, p, plen, rdlen))
                   1427:                  return 0;
                   1428:                
                   1429:                if (rdlen >= 2 && p[0] == 0)
                   1430:                  {
                   1431:                    /* If we can prove that there's no NS record, return that information. */
                   1432:                    if (nons && (p[2] & (0x80 >> T_NS)) != 0)
                   1433:                      *nons = 0;
                   1434:                
                   1435:                    /* A CNAME answer would also be valid, so if there's a CNAME is should 
                   1436:                       have been returned. */
                   1437:                    if ((p[2] & (0x80 >> T_CNAME)) != 0)
                   1438:                      return 0;
                   1439:                    
                   1440:                    /* If the SOA bit is set for a DS record, then we have the
1.1.1.3   misho    1441:                       DS from the wrong side of the delegation. For the root DS, 
                   1442:                       this is expected.  */
                   1443:                    if (name_labels != 0 && type == T_DS && (p[2] & (0x80 >> T_SOA)) != 0)
1.1.1.2   misho    1444:                      return 0;
                   1445:                  }
                   1446: 
                   1447:                while (rdlen >= 2)
                   1448:                  {
                   1449:                    if (p[0] == type >> 8)
                   1450:                      {
                   1451:                        /* Does the NSEC3 say our type exists? */
                   1452:                        if (offset < p[1] && (p[offset+2] & mask) != 0)
                   1453:                          return 0;
                   1454:                        
1.1.1.3   misho    1455:                        break; /* finished checking */
1.1.1.2   misho    1456:                      }
                   1457:                    
                   1458:                    rdlen -= p[1];
                   1459:                    p +=  p[1];
                   1460:                  }
                   1461:                
                   1462:                return 1;
                   1463:              }
                   1464:            else if (rc < 0)
                   1465:              {
                   1466:                /* Normal case, hash falls between NSEC3 name-hash and next domain name-hash,
                   1467:                   wrap around case, name-hash falls between NSEC3 name-hash and end */
                   1468:                if (memcmp(p, digest, digest_len) >= 0 || memcmp(workspace2, p, digest_len) >= 0)
                   1469:                  {
                   1470:                    if ((flags & 0x01) && nons) /* opt out */
                   1471:                      *nons = 0;
                   1472: 
                   1473:                    return 1;
                   1474:                  }
                   1475:              }
                   1476:            else 
                   1477:              {
                   1478:                /* wrap around case, name falls between start and next domain name */
                   1479:                if (memcmp(workspace2, p, digest_len) >= 0 && memcmp(p, digest, digest_len) >= 0)
                   1480:                  {
                   1481:                    if ((flags & 0x01) && nons) /* opt out */
                   1482:                      *nons = 0;
                   1483: 
                   1484:                    return 1;
                   1485:                  }
                   1486:              }
                   1487:          }
                   1488:       }
                   1489: 
                   1490:   return 0;
                   1491: }
                   1492: 
1.1       misho    1493: static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, unsigned char **nsecs, int nsec_count,
1.1.1.2   misho    1494:                                     char *workspace1, char *workspace2, char *name, int type, char *wildname, int *nons)
1.1       misho    1495: {
                   1496:   unsigned char *salt, *p, *digest;
1.1.1.2   misho    1497:   int digest_len, i, iterations, salt_len, base32_len, algo = 0;
1.1       misho    1498:   struct nettle_hash const *hash;
                   1499:   char *closest_encloser, *next_closest, *wildcard;
1.1.1.2   misho    1500:   
                   1501:   if (nons)
                   1502:     *nons = 1;
                   1503:   
1.1       misho    1504:   /* Look though the NSEC3 records to find the first one with 
1.1.1.2   misho    1505:      an algorithm we support.
1.1       misho    1506: 
                   1507:      Take the algo, iterations, and salt of that record
                   1508:      as the ones we're going to use, and prune any 
                   1509:      that don't match. */
                   1510:   
                   1511:   for (i = 0; i < nsec_count; i++)
                   1512:     {
                   1513:       if (!(p = skip_name(nsecs[i], header, plen, 15)))
1.1.1.2   misho    1514:        return 0; /* bad packet */
1.1       misho    1515:       
1.1.1.4 ! misho    1516:      p += 10; /* type, class, TTL, rdlen */
1.1       misho    1517:       algo = *p++;
                   1518:       
1.1.1.2   misho    1519:       if ((hash = hash_find(nsec3_digest_name(algo))))
1.1       misho    1520:        break; /* known algo */
                   1521:     }
                   1522: 
                   1523:   /* No usable NSEC3s */
                   1524:   if (i == nsec_count)
1.1.1.2   misho    1525:     return 0;
1.1       misho    1526: 
                   1527:   p++; /* flags */
1.1.1.2   misho    1528: 
1.1       misho    1529:   GETSHORT (iterations, p);
1.1.1.2   misho    1530:   /* Upper-bound iterations, to avoid DoS.
                   1531:      Strictly, there are lower bounds for small keys, but
                   1532:      since we don't have key size info here, at least limit
                   1533:      to the largest bound, for 4096-bit keys. RFC 5155 10.3 */
                   1534:   if (iterations > 2500)
                   1535:     return 0;
                   1536:   
1.1       misho    1537:   salt_len = *p++;
                   1538:   salt = p;
                   1539:   if (!CHECK_LEN(header, salt, plen, salt_len))
1.1.1.2   misho    1540:     return 0; /* bad packet */
1.1       misho    1541:     
                   1542:   /* Now prune so we only have NSEC3 records with same iterations, salt and algo */
                   1543:   for (i = 0; i < nsec_count; i++)
                   1544:     {
                   1545:       unsigned char *nsec3p = nsecs[i];
1.1.1.2   misho    1546:       int this_iter, flags;
1.1       misho    1547: 
                   1548:       nsecs[i] = NULL; /* Speculative, will be restored if OK. */
                   1549:       
                   1550:       if (!(p = skip_name(nsec3p, header, plen, 15)))
1.1.1.2   misho    1551:        return 0; /* bad packet */
1.1       misho    1552:       
                   1553:       p += 10; /* type, class, TTL, rdlen */
                   1554:       
                   1555:       if (*p++ != algo)
                   1556:        continue;
                   1557:  
1.1.1.2   misho    1558:       flags = *p++; /* flags */
1.1       misho    1559:       
1.1.1.2   misho    1560:       /* 5155 8.2 */
                   1561:       if (flags != 0 && flags != 1)
                   1562:        continue;
                   1563: 
1.1       misho    1564:       GETSHORT(this_iter, p);
                   1565:       if (this_iter != iterations)
                   1566:        continue;
                   1567: 
                   1568:       if (salt_len != *p++)
                   1569:        continue;
                   1570:       
                   1571:       if (!CHECK_LEN(header, p, plen, salt_len))
1.1.1.2   misho    1572:        return 0; /* bad packet */
1.1       misho    1573: 
                   1574:       if (memcmp(p, salt, salt_len) != 0)
                   1575:        continue;
                   1576: 
                   1577:       /* All match, put the pointer back */
                   1578:       nsecs[i] = nsec3p;
                   1579:     }
                   1580: 
1.1.1.2   misho    1581:   if ((digest_len = hash_name(name, &digest, hash, salt, salt_len, iterations)) == 0)
                   1582:     return 0;
                   1583:   
1.1.1.3   misho    1584:   if (check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count, nons, count_labels(name)))
1.1.1.2   misho    1585:     return 1;
1.1       misho    1586: 
1.1.1.2   misho    1587:   /* Can't find an NSEC3 which covers the name directly, we need the "closest encloser NSEC3" 
                   1588:      or an answer inferred from a wildcard record. */
1.1       misho    1589:   closest_encloser = name;
                   1590:   next_closest = NULL;
                   1591: 
                   1592:   do
                   1593:     {
                   1594:       if (*closest_encloser == '.')
                   1595:        closest_encloser++;
                   1596: 
1.1.1.2   misho    1597:       if (wildname && hostname_isequal(closest_encloser, wildname))
                   1598:        break;
                   1599: 
1.1       misho    1600:       if ((digest_len = hash_name(closest_encloser, &digest, hash, salt, salt_len, iterations)) == 0)
1.1.1.2   misho    1601:        return 0;
1.1       misho    1602:       
                   1603:       for (i = 0; i < nsec_count; i++)
                   1604:        if ((p = nsecs[i]))
                   1605:          {
                   1606:            if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
                   1607:                !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
1.1.1.2   misho    1608:              return 0;
1.1       misho    1609:          
                   1610:            if (digest_len == base32_len &&
                   1611:                memcmp(digest, workspace2, digest_len) == 0)
                   1612:              break; /* Gotit */
                   1613:          }
                   1614:       
                   1615:       if (i != nsec_count)
                   1616:        break;
                   1617:       
                   1618:       next_closest = closest_encloser;
                   1619:     }
                   1620:   while ((closest_encloser = strchr(closest_encloser, '.')));
                   1621:   
1.1.1.2   misho    1622:   if (!closest_encloser || !next_closest)
                   1623:     return 0;
                   1624:   
                   1625:   /* Look for NSEC3 that proves the non-existence of the next-closest encloser */
                   1626:   if ((digest_len = hash_name(next_closest, &digest, hash, salt, salt_len, iterations)) == 0)
                   1627:     return 0;
                   1628: 
1.1.1.3   misho    1629:   if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count, NULL, 1))
1.1.1.2   misho    1630:     return 0;
1.1       misho    1631:   
1.1.1.2   misho    1632:   /* Finally, check that there's no seat of wildcard synthesis */
                   1633:   if (!wildname)
1.1       misho    1634:     {
1.1.1.2   misho    1635:       if (!(wildcard = strchr(next_closest, '.')) || wildcard == next_closest)
                   1636:        return 0;
1.1       misho    1637:       
1.1.1.2   misho    1638:       wildcard--;
                   1639:       *wildcard = '*';
                   1640:       
                   1641:       if ((digest_len = hash_name(wildcard, &digest, hash, salt, salt_len, iterations)) == 0)
                   1642:        return 0;
                   1643:       
1.1.1.3   misho    1644:       if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count, NULL, 1))
1.1.1.2   misho    1645:        return 0;
                   1646:     }
                   1647:   
                   1648:   return 1;
                   1649: }
                   1650: 
1.1.1.3   misho    1651: static int prove_non_existence(struct dns_header *header, size_t plen, char *keyname, char *name, int qtype, int qclass, char *wildname, int *nons, int *nsec_ttl)
1.1.1.2   misho    1652: {
1.1.1.3   misho    1653:   static unsigned char **nsecset = NULL, **rrsig_labels = NULL;
                   1654:   static int nsecset_sz = 0, rrsig_labels_sz = 0;
1.1.1.2   misho    1655:   
                   1656:   int type_found = 0;
1.1.1.3   misho    1657:   unsigned char *auth_start, *p = skip_questions(header, plen);
1.1.1.2   misho    1658:   int type, class, rdlen, i, nsecs_found;
1.1.1.3   misho    1659:   unsigned long ttl;
1.1.1.2   misho    1660:   
                   1661:   /* Move to NS section */
                   1662:   if (!p || !(p = skip_section(p, ntohs(header->ancount), header, plen)))
                   1663:     return 0;
1.1.1.3   misho    1664: 
                   1665:   auth_start = p;
1.1.1.2   misho    1666:   
1.1.1.3   misho    1667:   for (nsecs_found = 0, i = 0; i < ntohs(header->nscount); i++)
1.1.1.2   misho    1668:     {
                   1669:       unsigned char *pstart = p;
                   1670:       
1.1.1.3   misho    1671:       if (!extract_name(header, plen, &p, daemon->workspacename, 1, 10))
1.1.1.2   misho    1672:        return 0;
1.1.1.3   misho    1673:          
1.1.1.2   misho    1674:       GETSHORT(type, p); 
                   1675:       GETSHORT(class, p);
1.1.1.3   misho    1676:       GETLONG(ttl, p);
1.1.1.2   misho    1677:       GETSHORT(rdlen, p);
                   1678: 
                   1679:       if (class == qclass && (type == T_NSEC || type == T_NSEC3))
1.1       misho    1680:        {
1.1.1.3   misho    1681:          if (nsec_ttl)
                   1682:            {
                   1683:              /* Limit TTL with sig TTL */
                   1684:              if (daemon->rr_status[ntohs(header->ancount) + i] < ttl)
                   1685:                ttl = daemon->rr_status[ntohs(header->ancount) + i];
                   1686:              *nsec_ttl = ttl;
                   1687:            }
                   1688:          
1.1.1.2   misho    1689:          /* No mixed NSECing 'round here, thankyouverymuch */
                   1690:          if (type_found != 0 && type_found != type)
                   1691:            return 0;
                   1692: 
                   1693:          type_found = type;
                   1694: 
                   1695:          if (!expand_workspace(&nsecset, &nsecset_sz, nsecs_found))
                   1696:            return 0; 
1.1       misho    1697:          
1.1.1.3   misho    1698:          if (type == T_NSEC)
                   1699:            {
                   1700:              /* If we're looking for NSECs, find the corresponding SIGs, to 
                   1701:                 extract the labels value, which we need in case the NSECs
                   1702:                 are the result of wildcard expansion.
                   1703:                 Note that the NSEC may not have been validated yet
                   1704:                 so if there are multiple SIGs, make sure the label value
                   1705:                 is the same in all, to avoid be duped by a rogue one.
                   1706:                 If there are no SIGs, that's an error */
                   1707:              unsigned char *p1 = auth_start;
                   1708:              int res, j, rdlen1, type1, class1;
                   1709:              
                   1710:              if (!expand_workspace(&rrsig_labels, &rrsig_labels_sz, nsecs_found))
                   1711:                return 0;
                   1712:              
                   1713:              rrsig_labels[nsecs_found] = NULL;
                   1714:              
                   1715:              for (j = ntohs(header->nscount); j != 0; j--)
                   1716:                {
                   1717:                  if (!(res = extract_name(header, plen, &p1, daemon->workspacename, 0, 10)))
                   1718:                    return 0;
                   1719: 
                   1720:                   GETSHORT(type1, p1); 
                   1721:                   GETSHORT(class1, p1);
                   1722:                   p1 += 4; /* TTL */
                   1723:                   GETSHORT(rdlen1, p1);
                   1724: 
                   1725:                   if (!CHECK_LEN(header, p1, plen, rdlen1))
                   1726:                     return 0;
                   1727:                   
                   1728:                   if (res == 1 && class1 == qclass && type1 == T_RRSIG)
                   1729:                     {
                   1730:                       int type_covered;
                   1731:                       unsigned char *psav = p1;
                   1732:                       
                   1733:                       if (rdlen1 < 18)
                   1734:                         return 0; /* bad packet */
                   1735: 
                   1736:                       GETSHORT(type_covered, p1);
                   1737: 
                   1738:                       if (type_covered == T_NSEC)
                   1739:                         {
                   1740:                           p1++; /* algo */
                   1741:                           
                   1742:                           /* labels field must be the same in every SIG we find. */
                   1743:                           if (!rrsig_labels[nsecs_found])
                   1744:                             rrsig_labels[nsecs_found] = p1;
                   1745:                           else if (*rrsig_labels[nsecs_found] != *p1) /* algo */
                   1746:                             return 0;
                   1747:                           }
                   1748:                       p1 = psav;
                   1749:                     }
                   1750:                   
                   1751:                   if (!ADD_RDLEN(header, p1, plen, rdlen1))
                   1752:                     return 0;
                   1753:                }
                   1754: 
                   1755:              /* Must have found at least one sig. */
                   1756:              if (!rrsig_labels[nsecs_found])
                   1757:                return 0;
                   1758:            }
                   1759: 
                   1760:          nsecset[nsecs_found++] = pstart;   
1.1.1.2   misho    1761:        }
                   1762:       
                   1763:       if (!ADD_RDLEN(header, p, plen, rdlen))
                   1764:        return 0;
                   1765:     }
                   1766:   
                   1767:   if (type_found == T_NSEC)
1.1.1.3   misho    1768:     return prove_non_existence_nsec(header, plen, nsecset, rrsig_labels, nsecs_found, daemon->workspacename, keyname, name, qtype, nons);
1.1.1.2   misho    1769:   else if (type_found == T_NSEC3)
                   1770:     return prove_non_existence_nsec3(header, plen, nsecset, nsecs_found, daemon->workspacename, keyname, name, qtype, wildname, nons);
                   1771:   else
                   1772:     return 0;
                   1773: }
                   1774: 
                   1775: /* Check signing status of name.
                   1776:    returns:
                   1777:    STAT_SECURE   zone is signed.
                   1778:    STAT_INSECURE zone proved unsigned.
                   1779:    STAT_NEED_DS  require DS record of name returned in keyname.
                   1780:    STAT_NEED_KEY require DNSKEY record of name returned in keyname.
                   1781:    name returned unaltered.
                   1782: */
                   1783: static int zone_status(char *name, int class, char *keyname, time_t now)
                   1784: {
                   1785:   int name_start = strlen(name); /* for when TA is root */
                   1786:   struct crec *crecp;
                   1787:   char *p;
                   1788: 
                   1789:   /* First, work towards the root, looking for a trust anchor.
                   1790:      This can either be one configured, or one previously cached.
                   1791:      We can assume, if we don't find one first, that there is
                   1792:      a trust anchor at the root. */
                   1793:   for (p = name; p; p = strchr(p, '.'))
                   1794:     {
                   1795:       if (*p == '.')
                   1796:        p++;
                   1797: 
                   1798:       if (cache_find_by_name(NULL, p, now, F_DS))
                   1799:        {
                   1800:          name_start = p - name;
                   1801:          break;
                   1802:        }
                   1803:     }
                   1804: 
                   1805:   /* Now work away from the trust anchor */
                   1806:   while (1)
                   1807:     {
                   1808:       strcpy(keyname, &name[name_start]);
                   1809:       
                   1810:       if (!(crecp = cache_find_by_name(NULL, keyname, now, F_DS)))
                   1811:        return STAT_NEED_DS;
                   1812:       
1.1.1.3   misho    1813:        /* F_DNSSECOK misused in DS cache records to non-existence of NS record.
1.1.1.2   misho    1814:          F_NEG && !F_DNSSECOK implies that we've proved there's no DS record here,
                   1815:          but that's because there's no NS record either, ie this isn't the start
                   1816:          of a zone. We only prove that the DNS tree below a node is unsigned when
                   1817:          we prove that we're at a zone cut AND there's no DS record. */
                   1818:       if (crecp->flags & F_NEG)
                   1819:        {
                   1820:          if (crecp->flags & F_DNSSECOK)
                   1821:            return STAT_INSECURE; /* proved no DS here */
                   1822:        }
                   1823:       else
                   1824:        {
                   1825:          /* If all the DS records have digest and/or sig algos we don't support,
                   1826:             then the zone is insecure. Note that if an algo
                   1827:             appears in the DS, then RRSIGs for that algo MUST
                   1828:             exist for each RRset: 4035 para 2.2  So if we find
                   1829:             a DS here with digest and sig we can do, we're entitled
                   1830:             to assume we can validate the zone and if we can't later,
                   1831:             because an RRSIG is missing we return BOGUS.
                   1832:          */
                   1833:          do 
1.1       misho    1834:            {
1.1.1.2   misho    1835:              if (crecp->uid == (unsigned int)class &&
1.1.1.3   misho    1836:                  ds_digest_name(crecp->addr.ds.digest) &&
                   1837:                  algo_digest_name(crecp->addr.ds.algo))
1.1.1.2   misho    1838:                break;
1.1       misho    1839:            }
1.1.1.2   misho    1840:          while ((crecp = cache_find_by_name(crecp, keyname, now, F_DS)));
                   1841: 
                   1842:          if (!crecp)
                   1843:            return STAT_INSECURE;
1.1       misho    1844:        }
1.1.1.2   misho    1845: 
                   1846:       if (name_start == 0)
                   1847:        break;
                   1848: 
                   1849:       for (p = &name[name_start-2]; (*p != '.') && (p != name); p--);
1.1       misho    1850:       
1.1.1.2   misho    1851:       if (p != name)
                   1852:         p++;
                   1853:       
                   1854:       name_start = p - name;
                   1855:     } 
1.1       misho    1856: 
1.1.1.2   misho    1857:   return STAT_SECURE;
                   1858: }
                   1859:        
                   1860: /* Validate all the RRsets in the answer and authority sections of the reply (4035:3.2.3) 
                   1861:    Return code:
                   1862:    STAT_SECURE   if it validates.
                   1863:    STAT_INSECURE at least one RRset not validated, because in unsigned zone.
                   1864:    STAT_BOGUS    signature is wrong, bad packet, no validation where there should be.
                   1865:    STAT_NEED_KEY need DNSKEY to complete validation (name is returned in keyname, class in *class)
1.1.1.3   misho    1866:    STAT_NEED_DS  need DS to complete validation (name is returned in keyname)
                   1867: 
                   1868:    daemon->rr_status points to a char array which corressponds to the RRs in the 
1.1.1.4 ! misho    1869:    answer and auth sections. This is set to >1 for each RR which is validated, and 0 for any which aren't.
1.1.1.3   misho    1870: 
                   1871:    When validating replies to DS records, we're only interested in the NSEC{3} RRs in the auth section.
                   1872:    Other RRs in that section missing sigs will not cause am INSECURE reply. We determine this mode
                   1873:    is the nons argument is non-NULL.
1.1.1.2   misho    1874: */
                   1875: int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, 
1.1.1.3   misho    1876:                          int *class, int check_unsigned, int *neganswer, int *nons, int *nsec_ttl)
1.1.1.2   misho    1877: {
                   1878:   static unsigned char **targets = NULL;
                   1879:   static int target_sz = 0;
1.1       misho    1880: 
1.1.1.2   misho    1881:   unsigned char *ans_start, *p1, *p2;
1.1.1.3   misho    1882:   int type1, class1, rdlen1 = 0, type2, class2, rdlen2, qclass, qtype, targetidx;
                   1883:   int i, j, rc = STAT_INSECURE;
                   1884:   int secure = STAT_SECURE;
1.1.1.4 ! misho    1885:    
1.1.1.3   misho    1886:   /* extend rr_status if necessary */
                   1887:   if (daemon->rr_status_sz < ntohs(header->ancount) + ntohs(header->nscount))
                   1888:     {
                   1889:       unsigned long *new = whine_malloc(sizeof(*daemon->rr_status) * (ntohs(header->ancount) + ntohs(header->nscount) + 64));
                   1890: 
                   1891:       if (!new)
                   1892:        return STAT_BOGUS;
1.1.1.2   misho    1893: 
1.1.1.3   misho    1894:       free(daemon->rr_status);
                   1895:       daemon->rr_status = new;
                   1896:       daemon->rr_status_sz = ntohs(header->ancount) + ntohs(header->nscount) + 64;
                   1897:     }
                   1898:   
                   1899:   memset(daemon->rr_status, 0, sizeof(*daemon->rr_status) * daemon->rr_status_sz);
                   1900:   
1.1.1.2   misho    1901:   if (neganswer)
                   1902:     *neganswer = 0;
1.1       misho    1903:   
1.1.1.2   misho    1904:   if (RCODE(header) == SERVFAIL || ntohs(header->qdcount) != 1)
1.1       misho    1905:     return STAT_BOGUS;
                   1906:   
1.1.1.2   misho    1907:   if (RCODE(header) != NXDOMAIN && RCODE(header) != NOERROR)
                   1908:     return STAT_INSECURE;
                   1909: 
                   1910:   p1 = (unsigned char *)(header+1);
1.1       misho    1911:   
1.1.1.2   misho    1912:    /* Find all the targets we're looking for answers to.
                   1913:      The zeroth array element is for the query, subsequent ones
1.1.1.4 ! misho    1914:      for CNAME targets, unless the query is for a CNAME or ANY. */
1.1.1.2   misho    1915: 
                   1916:   if (!expand_workspace(&targets, &target_sz, 0))
1.1       misho    1917:     return STAT_BOGUS;
                   1918:   
1.1.1.2   misho    1919:   targets[0] = p1;
                   1920:   targetidx = 1;
                   1921:    
1.1       misho    1922:   if (!extract_name(header, plen, &p1, name, 1, 4))
                   1923:     return STAT_BOGUS;
1.1.1.2   misho    1924:   
1.1       misho    1925:   GETSHORT(qtype, p1);
                   1926:   GETSHORT(qclass, p1);
                   1927:   ans_start = p1;
                   1928:  
1.1.1.2   misho    1929:   /* Can't validate an RRSIG query */
1.1       misho    1930:   if (qtype == T_RRSIG)
                   1931:     return STAT_INSECURE;
1.1.1.2   misho    1932:   
1.1.1.4 ! misho    1933:   if (qtype != T_CNAME && qtype != T_ANY)
1.1.1.2   misho    1934:     for (j = ntohs(header->ancount); j != 0; j--) 
                   1935:       {
                   1936:        if (!(p1 = skip_name(p1, header, plen, 10)))
                   1937:          return STAT_BOGUS; /* bad packet */
                   1938:        
                   1939:        GETSHORT(type2, p1); 
                   1940:        p1 += 6; /* class, TTL */
                   1941:        GETSHORT(rdlen2, p1);  
                   1942:        
                   1943:        if (type2 == T_CNAME)
                   1944:          {
                   1945:            if (!expand_workspace(&targets, &target_sz, targetidx))
                   1946:              return STAT_BOGUS;
                   1947:            
                   1948:            targets[targetidx++] = p1; /* pointer to target name */
                   1949:          }
                   1950:        
                   1951:        if (!ADD_RDLEN(header, p1, plen, rdlen2))
                   1952:          return STAT_BOGUS;
                   1953:       }
1.1       misho    1954:   
                   1955:   for (p1 = ans_start, i = 0; i < ntohs(header->ancount) + ntohs(header->nscount); i++)
                   1956:     {
1.1.1.3   misho    1957:       if (i != 0 && !ADD_RDLEN(header, p1, plen, rdlen1))
                   1958:        return STAT_BOGUS;
                   1959:       
1.1       misho    1960:       if (!extract_name(header, plen, &p1, name, 1, 10))
                   1961:        return STAT_BOGUS; /* bad packet */
                   1962:       
                   1963:       GETSHORT(type1, p1);
                   1964:       GETSHORT(class1, p1);
                   1965:       p1 += 4; /* TTL */
                   1966:       GETSHORT(rdlen1, p1);
                   1967:       
                   1968:       /* Don't try and validate RRSIGs! */
1.1.1.3   misho    1969:       if (type1 == T_RRSIG)
                   1970:        continue;
                   1971:       
                   1972:       /* Check if we've done this RRset already */
                   1973:       for (p2 = ans_start, j = 0; j < i; j++)
1.1       misho    1974:        {
1.1.1.3   misho    1975:          if (!(rc = extract_name(header, plen, &p2, name, 0, 10)))
                   1976:            return STAT_BOGUS; /* bad packet */
                   1977:          
                   1978:          GETSHORT(type2, p2);
                   1979:          GETSHORT(class2, p2);
                   1980:          p2 += 4; /* TTL */
                   1981:          GETSHORT(rdlen2, p2);
1.1       misho    1982:          
1.1.1.3   misho    1983:          if (type2 == type1 && class2 == class1 && rc == 1)
                   1984:            break; /* Done it before: name, type, class all match. */
                   1985:          
                   1986:          if (!ADD_RDLEN(header, p2, plen, rdlen2))
                   1987:            return STAT_BOGUS;
                   1988:        }
                   1989:       
                   1990:       /* Done already: copy the validation status */
                   1991:       if (j != i)
                   1992:        daemon->rr_status[i] = daemon->rr_status[j];
                   1993:       else
                   1994:        {
1.1       misho    1995:          /* Not done, validate now */
1.1.1.3   misho    1996:          int sigcnt, rrcnt;
                   1997:          char *wildname;
                   1998:          
                   1999:          if (!explore_rrset(header, plen, class1, type1, name, keyname, &sigcnt, &rrcnt))
                   2000:            return STAT_BOGUS;
                   2001:          
                   2002:          /* No signatures for RRset. We can be configured to assume this is OK and return an INSECURE result. */
                   2003:          if (sigcnt == 0)
1.1       misho    2004:            {
1.1.1.3   misho    2005:              /* NSEC and NSEC3 records must be signed. We make this assumption elsewhere. */
                   2006:              if (type1 == T_NSEC || type1 == T_NSEC3)
1.1.1.4 ! misho    2007:                return STAT_BOGUS | DNSSEC_FAIL_NOSIG;
1.1.1.3   misho    2008:              else if (nons && i >= ntohs(header->ancount))
                   2009:                /* If we're validating a DS reply, rather than looking for the value of AD bit,
                   2010:                   we only care that NSEC and NSEC3 RRs in the auth section are signed. 
                   2011:                   Return SECURE even if others (SOA....) are not. */
                   2012:                rc = STAT_SECURE;
                   2013:              else
1.1       misho    2014:                {
1.1.1.3   misho    2015:                  /* unsigned RRsets in auth section are not BOGUS, but do make reply insecure. */
                   2016:                  if (check_unsigned && i < ntohs(header->ancount))
1.1.1.2   misho    2017:                    {
                   2018:                      rc = zone_status(name, class1, keyname, now);
1.1.1.4 ! misho    2019:                      if (STAT_ISEQUAL(rc, STAT_SECURE))
        !          2020:                        rc = STAT_BOGUS | DNSSEC_FAIL_NOSIG;
        !          2021:                      
1.1.1.3   misho    2022:                      if (class)
                   2023:                        *class = class1; /* Class for NEED_DS or NEED_KEY */
1.1.1.2   misho    2024:                    }
                   2025:                  else 
                   2026:                    rc = STAT_INSECURE; 
1.1       misho    2027:                  
1.1.1.4 ! misho    2028:                  if (!STAT_ISEQUAL(rc, STAT_INSECURE))
1.1.1.3   misho    2029:                    return rc;
1.1.1.2   misho    2030:                }
1.1.1.3   misho    2031:            }
                   2032:          else
                   2033:            {
1.1.1.2   misho    2034:              /* explore_rrset() gives us key name from sigs in keyname.
                   2035:                 Can't overwrite name here. */
                   2036:              strcpy(daemon->workspacename, keyname);
                   2037:              rc = zone_status(daemon->workspacename, class1, keyname, now);
1.1       misho    2038:              
1.1.1.4 ! misho    2039:              if (STAT_ISEQUAL(rc, STAT_BOGUS) || STAT_ISEQUAL(rc, STAT_NEED_KEY) || STAT_ISEQUAL(rc, STAT_NEED_DS))
1.1       misho    2040:                {
1.1.1.2   misho    2041:                  if (class)
1.1.1.3   misho    2042:                    *class = class1; /* Class for NEED_DS or NEED_KEY */
1.1.1.2   misho    2043:                  return rc;
1.1.1.3   misho    2044:                }
                   2045:              
                   2046:              /* Zone is insecure, don't need to validate RRset */
1.1.1.4 ! misho    2047:              if (STAT_ISEQUAL(rc, STAT_SECURE))
1.1.1.2   misho    2048:                {
1.1.1.3   misho    2049:                  unsigned long sig_ttl;
                   2050:                  rc = validate_rrset(now, header, plen, class1, type1, sigcnt,
                   2051:                                      rrcnt, name, keyname, &wildname, NULL, 0, 0, 0, &sig_ttl);
                   2052:                  
1.1.1.4 ! misho    2053:                  if (STAT_ISEQUAL(rc, STAT_BOGUS) || STAT_ISEQUAL(rc, STAT_NEED_KEY) || STAT_ISEQUAL(rc, STAT_NEED_DS))
1.1.1.3   misho    2054:                    {
                   2055:                      if (class)
                   2056:                        *class = class1; /* Class for DS or DNSKEY */
                   2057:                      return rc;
                   2058:                    } 
                   2059:                  
1.1.1.2   misho    2060:                  /* rc is now STAT_SECURE or STAT_SECURE_WILDCARD */
1.1.1.3   misho    2061:                  
                   2062:                  /* Note that RR is validated */
                   2063:                  daemon->rr_status[i] = sig_ttl;
                   2064:                   
1.1.1.2   misho    2065:                  /* Note if we've validated either the answer to the question
                   2066:                     or the target of a CNAME. Any not noted will need NSEC or
                   2067:                     to be in unsigned space. */
                   2068:                  for (j = 0; j <targetidx; j++)
                   2069:                    if ((p2 = targets[j]))
                   2070:                      {
1.1.1.3   misho    2071:                        int rc1;
                   2072:                        if (!(rc1 = extract_name(header, plen, &p2, name, 0, 10)))
1.1.1.2   misho    2073:                          return STAT_BOGUS; /* bad packet */
                   2074:                        
1.1.1.3   misho    2075:                        if (class1 == qclass && rc1 == 1 && (type1 == T_CNAME || type1 == qtype || qtype == T_ANY ))
1.1.1.2   misho    2076:                          targets[j] = NULL;
                   2077:                      }
1.1.1.3   misho    2078:                  
                   2079:                  /* An attacker replay a wildcard answer with a different
                   2080:                     answer and overlay a genuine RR. To prove this
                   2081:                     hasn't happened, the answer must prove that
                   2082:                     the genuine record doesn't exist. Check that here. 
                   2083:                     Note that we may not yet have validated the NSEC/NSEC3 RRsets. 
                   2084:                     That's not a problem since if the RRsets later fail
                   2085:                     we'll return BOGUS then. */
1.1.1.4 ! misho    2086:                  if (STAT_ISEQUAL(rc, STAT_SECURE_WILDCARD) &&
1.1.1.3   misho    2087:                      !prove_non_existence(header, plen, keyname, name, type1, class1, wildname, NULL, NULL))
1.1.1.4 ! misho    2088:                    return STAT_BOGUS | DNSSEC_FAIL_NONSEC;
1.1.1.3   misho    2089: 
                   2090:                  rc = STAT_SECURE;
1.1       misho    2091:                }
                   2092:            }
                   2093:        }
                   2094: 
1.1.1.4 ! misho    2095:       if (STAT_ISEQUAL(rc, STAT_INSECURE))
1.1.1.3   misho    2096:        secure = STAT_INSECURE;
1.1       misho    2097:     }
                   2098: 
1.1.1.2   misho    2099:   /* OK, all the RRsets validate, now see if we have a missing answer or CNAME target. */
1.1.1.4 ! misho    2100:   for (j = 0; j <targetidx; j++)
        !          2101:     if ((p2 = targets[j]))
        !          2102:       {
        !          2103:        if (neganswer)
        !          2104:          *neganswer = 1;
        !          2105:        
        !          2106:        if (!extract_name(header, plen, &p2, name, 1, 10))
        !          2107:          return STAT_BOGUS; /* bad packet */
        !          2108:        
        !          2109:        /* NXDOMAIN or NODATA reply, unanswered question is (name, qclass, qtype) */
        !          2110:        
        !          2111:        /* For anything other than a DS record, this situation is OK if either
        !          2112:           the answer is in an unsigned zone, or there's a NSEC records. */
        !          2113:        if (!prove_non_existence(header, plen, keyname, name, qtype, qclass, NULL, nons, nsec_ttl))
        !          2114:          {
        !          2115:            /* Empty DS without NSECS */
        !          2116:            if (qtype == T_DS)
        !          2117:              return STAT_BOGUS | DNSSEC_FAIL_NONSEC;
        !          2118:            
        !          2119:            if (!STAT_ISEQUAL((rc = zone_status(name, qclass, keyname, now)), STAT_SECURE))
        !          2120:              {
        !          2121:                if (class)
        !          2122:                  *class = qclass; /* Class for NEED_DS or NEED_KEY */
        !          2123:                return rc;
        !          2124:              } 
        !          2125:            
        !          2126:            return STAT_BOGUS | DNSSEC_FAIL_NONSEC; /* signed zone, no NSECs */
        !          2127:          }
        !          2128:       }
1.1       misho    2129:   
1.1.1.3   misho    2130:   return secure;
1.1       misho    2131: }
                   2132: 
                   2133: 
                   2134: /* Compute keytag (checksum to quickly index a key). See RFC4034 */
                   2135: int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen)
                   2136: {
                   2137:   if (alg == 1)
                   2138:     {
                   2139:       /* Algorithm 1 (RSAMD5) has a different (older) keytag calculation algorithm.
                   2140:          See RFC4034, Appendix B.1 */
                   2141:       return key[keylen-4] * 256 + key[keylen-3];
                   2142:     }
                   2143:   else
                   2144:     {
                   2145:       unsigned long ac = flags + 0x300 + alg;
                   2146:       int i;
                   2147: 
                   2148:       for (i = 0; i < keylen; ++i)
                   2149:         ac += (i & 1) ? key[i] : key[i] << 8;
                   2150: 
                   2151:       ac += (ac >> 16) & 0xffff;
                   2152:       return ac & 0xffff;
                   2153:     }
                   2154: }
                   2155: 
1.1.1.2   misho    2156: size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, 
1.1.1.3   misho    2157:                             int type, int edns_pktsz)
1.1       misho    2158: {
                   2159:   unsigned char *p;
1.1.1.2   misho    2160:   size_t ret;
1.1       misho    2161: 
                   2162:   header->qdcount = htons(1);
                   2163:   header->ancount = htons(0);
                   2164:   header->nscount = htons(0);
                   2165:   header->arcount = htons(0);
                   2166: 
                   2167:   header->hb3 = HB3_RD; 
                   2168:   SET_OPCODE(header, QUERY);
                   2169:   /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
                   2170:      this allows it to select auth servers when one is returning bad data. */
                   2171:   header->hb4 = option_bool(OPT_DNSSEC_DEBUG) ? HB4_CD : 0;
                   2172: 
                   2173:   /* ID filled in later */
                   2174: 
                   2175:   p = (unsigned char *)(header+1);
                   2176:        
1.1.1.3   misho    2177:   p = do_rfc1035_name(p, name, NULL);
1.1       misho    2178:   *p++ = 0;
                   2179:   PUTSHORT(type, p);
                   2180:   PUTSHORT(class, p);
                   2181: 
1.1.1.2   misho    2182:   ret = add_do_bit(header, p - (unsigned char *)header, end);
1.1       misho    2183: 
1.1.1.2   misho    2184:   if (find_pseudoheader(header, ret, NULL, &p, NULL, NULL))
                   2185:     PUTSHORT(edns_pktsz, p);
1.1       misho    2186: 
1.1.1.2   misho    2187:   return ret;
1.1       misho    2188: }
                   2189: 
1.1.1.4 ! misho    2190: int errflags_to_ede(int status)
        !          2191: {
        !          2192:   /* We can end up with more than one flag set for some errors,
        !          2193:      so this encodes a rough priority so the (eg) No sig is reported
        !          2194:      before no-unexpired-sig. */
        !          2195: 
        !          2196:   if (status & DNSSEC_FAIL_NYV)
        !          2197:     return EDE_SIG_NYV;
        !          2198:   else if (status & DNSSEC_FAIL_EXP)
        !          2199:     return EDE_SIG_EXP;
        !          2200:   else if (status & DNSSEC_FAIL_NOKEYSUP)
        !          2201:     return EDE_USUPDNSKEY;
        !          2202:   else if (status & DNSSEC_FAIL_NOZONE)
        !          2203:     return EDE_NO_ZONEKEY;
        !          2204:   else if (status & DNSSEC_FAIL_NOKEY)
        !          2205:     return EDE_NO_DNSKEY;
        !          2206:   else if (status & DNSSEC_FAIL_NODSSUP)
        !          2207:     return EDE_USUPDS;
        !          2208:   else if (status & DNSSEC_FAIL_NONSEC)
        !          2209:     return EDE_NO_NSEC;
        !          2210:   else if (status & DNSSEC_FAIL_INDET)
        !          2211:     return EDE_DNSSEC_IND;
        !          2212:   else if (status & DNSSEC_FAIL_NOSIG)
        !          2213:     return EDE_NO_RRSIG;
        !          2214:   else
        !          2215:     return EDE_UNSET;
        !          2216: }
1.1       misho    2217: #endif /* HAVE_DNSSEC */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>