示例#1
0
/*
 * Parse rdata portion of an RRSIG Resource Record.
 * Returns the number of bytes in the RRSIG rdata portion that were parsed.
 * Caller assumes responsiblity for allocated dnskey_rdata memory.
 */
int
val_parse_rrsig_rdata(const u_char *buf, size_t buflen,
                      val_rrsig_rdata_t * rdata)
{
    size_t index = 0;
    const u_char   *cp;
    size_t namelen;
    int retval;

    if (!rdata || !buf)
        return VAL_BAD_ARGUMENT;

    if (index + 18 > buflen)
        return VAL_BAD_ARGUMENT;

    cp = buf;
    VAL_GET16(rdata->type_covered, cp);
    index += 2;

    rdata->algorithm = (u_char) (buf[index]);
    index += 1;

    rdata->labels = (u_char) (buf[index]);
    index += 1;

    cp = (buf + index);
    VAL_GET32(rdata->orig_ttl, cp);
    index += 4;

    VAL_GET32(rdata->sig_expr, cp);
    index += 4;

    VAL_GET32(rdata->sig_incp, cp);
    index += 4;

    VAL_GET16(rdata->key_tag, cp);
    index += 2;

    if (VAL_NO_ERROR != 
            (retval = val_parse_dname(buf, buflen, index, 
                        (char *) rdata->signer_name,
                        &namelen))) {
        return retval;
    }
    index += namelen;

    rdata->signature_len = (buflen > index) ? (buflen - index) : 0;

    if (rdata->signature_len > 0) {
        rdata->signature =
            (u_char *) MALLOC(rdata->signature_len * sizeof(u_char));
        if (rdata->signature == NULL)
            return VAL_OUT_OF_MEMORY;
        memcpy(rdata->signature, buf + index, rdata->signature_len);
        index += rdata->signature_len;
    } else
        rdata->signature = NULL;

    return VAL_NO_ERROR;
}
示例#2
0
/*
 * Returns VAL_NO_ERROR on success, other values on failure 
 */
static int
rsamd5_parse_public_key(const u_char *buf, size_t buflen, RSA * rsa)
{
    int             index = 0;
    const u_char   *cp;
    u_int16_t       exp_len = 0x0000;
    BIGNUM         *bn_exp;
    BIGNUM         *bn_mod;

    if (!rsa || buflen == 0)
        return VAL_BAD_ARGUMENT;

    cp = buf;

    if (buf[index] == 0) {

        if (buflen < 3)
            return VAL_BAD_ARGUMENT;

        index += 1;
        cp = (buf + index);
        VAL_GET16(exp_len, cp);
        index += 2;
    } else {
        exp_len += buf[index];
        index += 1;
    }

    if (exp_len > buflen - index) {
        return VAL_BAD_ARGUMENT;
    }
    
    /*
     * Extract the exponent 
     */
    bn_exp = BN_bin2bn(buf + index, exp_len, NULL);

    index += exp_len;

    if (buflen <= index) {
        return VAL_BAD_ARGUMENT;
    }

    /*
     * Extract the modulus 
     */
    bn_mod = BN_bin2bn(buf + index, buflen - index, NULL);

    rsa->e = bn_exp;
    rsa->n = bn_mod;

    return VAL_NO_ERROR;        /* success */
}
示例#3
0
/*
 * Parse rdata portion of a DS Resource Record.
 */
int
val_parse_ds_rdata(const u_char *buf, size_t buflen,
                   val_ds_rdata_t * rdata)
{
    size_t index = 0;
    const u_char   *cp = buf;

    if (!rdata || !buf)
        return VAL_BAD_ARGUMENT;

    if (index + 2 + 1 + 1 > buflen)
        return VAL_BAD_ARGUMENT;

    VAL_GET16(rdata->d_keytag, cp);
    index += 2;

    rdata->d_algo = (u_char) (buf[index]);
    index += 1;

    rdata->d_type = (u_char) (buf[index]);
    index += 1;

    /*
     * Only SHA-1 is understood 
     */
    if (rdata->d_type == ALG_DS_HASH_SHA1)
        rdata->d_hash_len = SHA_DIGEST_LENGTH;
    else if (rdata->d_type == ALG_DS_HASH_SHA256)
        rdata->d_hash_len = SHA256_DIGEST_LENGTH;
    else
        return VAL_NOT_IMPLEMENTED;

    if (index + rdata->d_hash_len > buflen)
        return VAL_BAD_ARGUMENT;

    rdata->d_hash =
        (u_char *) MALLOC(rdata->d_hash_len * sizeof(u_char));
    if (rdata->d_hash == NULL)
        return VAL_OUT_OF_MEMORY;

    memcpy(rdata->d_hash, buf + index, rdata->d_hash_len);
    index += rdata->d_hash_len;

    return VAL_NO_ERROR;
}
示例#4
0
/*
 * Parse rdata portion of a DNSKEY Resource Record.
 * Returns the number of bytes in the DNSKEY rdata portion that were parsed on success. 
 * Returns 0 on failure.
 */
int
val_parse_dnskey_rdata(const u_char *buf, size_t buflen,
                       val_dnskey_rdata_t * rdata)
{
    size_t index = 0;
    const u_char   *cp;

    if (!rdata || !buf)
        return VAL_BAD_ARGUMENT;

    if (index + 4 > buflen)
        return VAL_BAD_ARGUMENT;

    cp = buf;
    VAL_GET16(rdata->flags, cp);
    index += 2;

    rdata->protocol = (u_char) (buf[index]);
    index += 1;

    rdata->algorithm = (u_char) (buf[index]);
    index += 1;

    rdata->public_key_len = (buflen > index) ? (buflen - index) : 0;

    if (rdata->public_key_len > 0) {
        rdata->public_key =
            (u_char *) MALLOC(rdata->public_key_len * sizeof(u_char));
        if (rdata->public_key == NULL)
            return VAL_OUT_OF_MEMORY;
        memcpy(rdata->public_key, buf + index, rdata->public_key_len);
        index += rdata->public_key_len;
    } else
        rdata->public_key = NULL;

    if (rdata->algorithm == ALG_RSAMD5) {
        rdata->key_tag = rsamd5_keytag(buf, buflen);
    } else {
        rdata->key_tag = keytag(buf, buflen);
    }

    return VAL_NO_ERROR;
}
static int
process_packet(val_context_t *context)
{
    HEADER         *query_header, *response_header;
    u_char         *pos;
    int             q_name_len, rc;
    u_int16_t       type_h, class_h;

    struct sockaddr from;
    socklen_t       from_len;

    u_char          query[4096], response[4096];
    int             query_size, response_size;

    /*
     * get a packet
     */
    from_len = sizeof(from);
    memset(&from, 0x0, sizeof(from));
    do {
        rc = recvfrom(listen_fd, query, sizeof(query), 0, &from,
                      &from_len);
        if (rc < 0 && errno != EINTR) {
            // xxx-rks: log err msg
            break;
        }
    } while (rc < 0);
    if (rc < 0)
        return rc;

    query_size = rc;
    if (query_size < (sizeof(HEADER) + 1))
        return -1;

    query_header = (HEADER *) query;

    /*
     * get query name
     */
    pos = &query[sizeof(HEADER)];
    q_name_len = wire_name_length(pos);
    pos += q_name_len;

    /*
     * get class and type
     */
    VAL_GET16(type_h, pos);
    VAL_GET16(class_h, pos);

    response_size = sizeof(response);
    
    get_results(context, "test", (char *)&query[sizeof(HEADER)], (int)class_h,
                (int)type_h, response, &response_size, 0);

    /*
     * check to see if we need a dummy response
     */
    val_log(NULL, LOG_DEBUG, "XXX-RKS: handle no response");
    if (0 == response_size) {
        // no response; generate dummy/nxdomain response?
        return 1;
    }

    response_header = (HEADER*)response;
    response_header->id = query_header->id;

    /*
     * send response
     */
    do {
        rc = sendto(listen_fd, response, response_size, 0, &from,
                    sizeof(from));
        if (rc < 0 && errno != EINTR) {
            // xxx-rks: log err msg
            break;
        }
    } while (rc < 0);
    if (rc > 0) {
        val_log(NULL, LOG_DEBUG, "sent %d bytes", rc);
    }

    return 0;                   /* no error */
}
示例#6
0
val_nsec3_rdata_t *
val_parse_nsec3_rdata(u_char * rr_rdata, size_t rdatalen,
                      val_nsec3_rdata_t * nd)
{
    u_char       *cp;
    size_t        nexthashlen, retlen;
    u_char       *nexthash;

    if (nd == NULL)
        return NULL;

    cp = rr_rdata;

    if (rdatalen < 5) {
        /*
         * somethings wrong 
         */
        return NULL;
    }
    nd->alg = *cp;
    cp += 1;
    nd->flags = *cp;
    cp += 1;
    VAL_GET16(nd->iterations, cp);
    nd->saltlen = *cp;
    cp += 1;
    if ((cp - rr_rdata) >= rdatalen)
        return NULL;

    nd->salt = cp;
    cp += nd->saltlen;
    if ((cp - rr_rdata) >= rdatalen)
        return NULL;

    nexthashlen = *cp;
    cp += 1;
    if ((cp - rr_rdata) >= rdatalen)
        return NULL;

    nexthash = cp;
    cp += nexthashlen;
    /* note that the next check does not check >= */
    /* this is because the bit field can be empty */
    if ((cp - rr_rdata) > rdatalen)
        return NULL;

    base32hex_encode(nexthash, nexthashlen, &(nd->nexthash),
                     &retlen);
    nd->nexthashlen = (u_char)retlen;
    if (retlen > nd->nexthashlen)
        return NULL;

    /* bit field can be empty */
    if (cp - rr_rdata == rdatalen) {
        nd->bit_field = 0;
    } else { 
        nd->bit_field = cp - rr_rdata;
    }

    return nd;
}