Exemple #1
0
void
val_log_rrsig_rdata(const val_context_t * ctx, int level,
                    const char *prefix, val_rrsig_rdata_t * rdata)
{
    char            ctime_buf1[1028], ctime_buf2[1028];
    char            buf[1028];
    struct timeval  tv_sig1, tv_sig2;

    if (rdata) {
        if (!prefix)
            prefix = "";

        memset(&tv_sig1, 0, sizeof(tv_sig1));
        memset(&tv_sig2, 0, sizeof(tv_sig2));
        tv_sig1.tv_sec = rdata->sig_expr; 
        tv_sig2.tv_sec = rdata->sig_incp; 

        GET_TIME_BUF((const time_t *)(&tv_sig1.tv_sec), ctime_buf1);
        GET_TIME_BUF((const time_t *)(&tv_sig2.tv_sec), ctime_buf2);

        val_log(ctx, level, "%s Type=%d Algo=%d[%s] Labels=%d OrgTTL=%d "
                "SigExp=%s SigIncp=%s KeyTag=%d[0x %04x] Signer=%s Sig=%s",
                prefix, rdata->algorithm,
                get_algorithm_string(rdata->algorithm), rdata->labels,
                rdata->orig_ttl,
                ctime_buf1, ctime_buf2,
                rdata->key_tag, rdata->key_tag, rdata->signer_name,
                get_base64_string(rdata->signature, rdata->signature_len,
                                  buf, 1024));
    }
}
Exemple #2
0
void
val_log_assertion_pfx(const val_context_t * ctx, int level,
                      const char *prefix, const char * name_pr,
                      struct val_authentication_chain *next_as)
{
    char            name_buf[INET6_ADDRSTRLEN + 1];
    const char     *serv_pr;
    int             tag = 0;
    int             class_h;
    int             type_h;
    struct          val_rr_rec  *data;
    struct          sockaddr *serv;
    val_astatus_t   status;
    struct val_rr_rec  *curkey;
#undef VAL_LOG_SIG
#ifdef VAL_LOG_SIG
    struct          val_rr_rec  *sig;
    struct val_rr_rec  *cursig;
#endif


    if (next_as == NULL)
        return;

    class_h = next_as->val_ac_rrset->val_rrset_class;
    type_h = next_as->val_ac_rrset->val_rrset_type;
    data = next_as->val_ac_rrset->val_rrset_data;
#ifdef VAL_LOG_SIG
    sig = next_as->val_ac_rrset->val_rrset_sig;
#endif
    serv = next_as->val_ac_rrset->val_rrset_server;
    status = next_as->val_ac_status;

    if (NULL == prefix)
        prefix = "";

    if (serv)
        serv_pr =
            ((serv_pr =
              val_get_ns_string(serv, name_buf, sizeof(name_buf))) == NULL) ?  "VAL_CACHE" : serv_pr;
    else
        serv_pr = "NULL";

    if (type_h == ns_t_dnskey) {
        for (curkey = data; curkey; curkey = curkey->rr_next) {
            if ((curkey->rr_status == VAL_AC_VERIFIED_LINK) ||
                (curkey->rr_status == VAL_AC_TRUST_POINT) ||
                (curkey->rr_status == VAL_AC_UNKNOWN_ALGORITHM_LINK)) {
                /*
                 * Extract the key tag 
                 */
                val_dnskey_rdata_t dnskey;
                if (VAL_NO_ERROR != val_parse_dnskey_rdata(curkey->rr_rdata,
                                       curkey->rr_rdata_length, &dnskey)) {
                    val_log(ctx, LOG_INFO, "val_log_assertion_pfx(): Cannot parse DNSKEY data");
                } else {
                    tag = dnskey.key_tag;
                    if (dnskey.public_key)
                        FREE(dnskey.public_key);
                }
                break;
            }
        }
    }

    if (tag != 0) {
        val_log(ctx, level,
                "%sname=%s class=%s type=%s[tag=%d] from-server=%s "
                "status=%s:%d", prefix, name_pr, p_class(class_h),
                p_type(type_h), tag, serv_pr, p_ac_status(status), status);
    } else {
        val_log(ctx, level,
                "%sname=%s class=%s type=%s from-server=%s status=%s:%d",
                prefix, name_pr, p_class(class_h), p_type(type_h), serv_pr,
                p_ac_status(status), status);
    }
#ifdef VAL_LOG_SIG
    for (cursig = sig; cursig; cursig = cursig->rr_next) {
        char incpTime[1028];
        char exprTime[1028];
        struct timeval  tv_sig;
        val_rrsig_rdata_t rrsig;

        val_parse_rrsig_rdata(cursig->rr_rdata, cursig->rr_rdata_length, &rrsig);

        memset(&tv_sig, 0, sizeof(tv_sig));
        tv_sig.tv_sec = rrsig.sig_incp;
        GET_TIME_BUF((const time_t *)(&tv_sig.tv_sec), incpTime);

        memset(&tv_sig, 0, sizeof(tv_sig));
        tv_sig.tv_sec = rrsig.sig_expr;
        GET_TIME_BUF((const time_t *)(&tv_sig.tv_sec), exprTime);

        val_log(ctx, level,
                "%s    ->tag=%d status=%s sig-incep=%s sig-expr=%s",
                prefix, rrsig.key_tag,
                p_ac_status(cursig->rr_status),
                incpTime, exprTime);
    }
#endif

#ifdef VAL_LOG_SIG
    struct val_rr_rec  *rr;
    struct val_rr_rec  *sig = next_as->val_ac_rrset->val_rrset_sig;
    for (rr = data; rr; rr = rr->rr_next) {
        val_log(ctx, level, "    data_status=%s:%d",
                p_ac_status(rr->rr_status), rr->rr_status);
    }
    for (rr = sig; rr; rr = rr->rr_next) {
        val_log(ctx, level, "    sig_status=%s:%d",
                p_ac_status(rr->rr_status), rr->rr_status);
    }
#endif
}
Exemple #3
0
/*
 * Verify a signature, given the data and the dnskey 
 */
static int 
val_sigverify(val_context_t * ctx,
              int is_a_wildcard,
              const u_char *data,
              size_t data_len,
              const val_dnskey_rdata_t * dnskey,
              const val_rrsig_rdata_t * rrsig,
              val_astatus_t * dnskey_status, val_astatus_t * sig_status,
              int clock_skew)
{
    struct timeval  tv;
    struct timeval  tv_sig;

    /** Inputs to this function have already been NULL-checked **/

    /*
     * Check if the dnskey is a zone key 
     */
    if ((dnskey->flags & ZONE_KEY_FLAG) == 0) {
        val_log(ctx, LOG_INFO, "val_sigverify(): DNSKEY with tag=%d is not a zone key", dnskey->key_tag);
        *dnskey_status = VAL_AC_INVALID_KEY;
        return 0;
    }

    /*
     * Check dnskey protocol value 
     */
    if (dnskey->protocol != 3) {
        val_log(ctx, LOG_INFO,
                "val_sigverify(): Invalid protocol field in DNSKEY with tag=%d: %d",
                dnskey->protocol, dnskey->key_tag);
        *dnskey_status = VAL_AC_UNKNOWN_DNSKEY_PROTOCOL;
        return 0;
    }

    /*
     * Match dnskey and rrsig algorithms 
     */
    if (dnskey->algorithm != rrsig->algorithm) {
        val_log(ctx, LOG_INFO,
                "val_sigverify(): Algorithm mismatch between DNSKEY (%d) and RRSIG (%d) records.",
                dnskey->algorithm, rrsig->algorithm);
        *sig_status = VAL_AC_RRSIG_ALGORITHM_MISMATCH;
        return 0;
    }


    if (clock_skew >= 0) {
        
        /*
         * Check signature inception and expiration times 
         */
        gettimeofday(&tv, NULL);
        if (tv.tv_sec < rrsig->sig_incp) {
            if (tv.tv_sec < rrsig->sig_incp - clock_skew) {
                char            currTime[1028];
                char            incpTime[1028];

                memset(&tv_sig, 0, sizeof(tv_sig));
                tv_sig.tv_sec = rrsig->sig_incp;

                GET_TIME_BUF((const time_t *)(&tv.tv_sec), currTime);
                GET_TIME_BUF((const time_t *)(&tv_sig.tv_sec), incpTime);

                val_log(ctx, LOG_INFO,
                        "val_sigverify(): Signature not yet valid. Current time (%s) is less than signature inception time (%s).",
                        currTime, incpTime);
                *sig_status = VAL_AC_RRSIG_NOTYETACTIVE;
                return 0;
            } else {
                val_log(ctx, LOG_DEBUG,
                        "val_sigverify(): Signature not yet valid, but within acceptable skew.");
            }
    
        }
    
        if (tv.tv_sec > rrsig->sig_expr) {
            if (tv.tv_sec > rrsig->sig_expr + clock_skew) {
                char            currTime[1028];
                char            exprTime[1028];

                memset(&tv_sig, 0, sizeof(tv_sig));
                tv_sig.tv_sec = rrsig->sig_expr;

                memset(currTime, 0, sizeof(currTime));
                memset(exprTime, 0, sizeof(exprTime));
                GET_TIME_BUF((const time_t *)(&tv.tv_sec), currTime);
                GET_TIME_BUF((const time_t *)(&tv_sig.tv_sec), exprTime);

                val_log(ctx, LOG_INFO,
                        "val_sigverify(): Signature expired. Current time (%s) is greater than signature expiration time (%s).",
                        currTime, exprTime);
                *sig_status = VAL_AC_RRSIG_EXPIRED;
                return 0;
            } else {
                val_log(ctx, LOG_DEBUG,
                        "val_sigverify(): Signature expired, but within acceptable skew.");
            }
        }
    } else {
        val_log(ctx, LOG_DEBUG,
                "val_sigverify(): Not checking inception and expiration times on signatures.");
    }

    switch (rrsig->algorithm) {

    case ALG_RSAMD5:
        rsamd5_sigverify(ctx, data, data_len, dnskey, rrsig, 
                         dnskey_status, sig_status);
        break;

#ifdef LIBVAL_NSEC3
    case ALG_NSEC3_DSASHA1:
#endif
    case ALG_DSASHA1:
        dsasha1_sigverify(ctx, data, data_len, dnskey, rrsig,
                          dnskey_status, sig_status);
        break;

#ifdef LIBVAL_NSEC3
    case ALG_NSEC3_RSASHA1:
#endif
    case ALG_RSASHA1:
#ifdef HAVE_SHA_2
    case ALG_RSASHA256:
    case ALG_RSASHA512:
#endif
        rsasha_sigverify(ctx, data, data_len, dnskey, rrsig,
                          dnskey_status, sig_status);
        break;

#if defined(HAVE_SHA_2) && defined(HAVE_OPENSSL_ECDSA_H)
    case ALG_ECDSAP256SHA256:
    case ALG_ECDSAP384SHA384:
        ecdsa_sigverify(ctx, data, data_len, dnskey, rrsig,
                        dnskey_status, sig_status);
        break;
#endif

    default:
        val_log(ctx, LOG_INFO, "val_sigverify(): Unsupported algorithm %d.",
                rrsig->algorithm);
        *sig_status = VAL_AC_ALGORITHM_NOT_SUPPORTED;
        *dnskey_status = VAL_AC_ALGORITHM_NOT_SUPPORTED;
        break;
    }

    if (*sig_status == VAL_AC_RRSIG_VERIFIED) {
        if (is_a_wildcard) {
            val_log(ctx, LOG_DEBUG, "val_sigverify(): Verified RRSIG is for a wildcard");
            if (clock_skew > 0)
                *sig_status = VAL_AC_WCARD_VERIFIED_SKEW;
            else
                *sig_status = VAL_AC_WCARD_VERIFIED;
        } else {
            if (clock_skew > 0)
                *sig_status = VAL_AC_RRSIG_VERIFIED_SKEW;
        }
        return 1;
    }

    return 0;
}