isc_result_t isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target, isc_uint32_t algorithm, isccc_region_t *secret) { unsigned char *hmac_rstart, *signed_rstart; isc_result_t result; if (algorithm == ISCCC_ALG_HMACMD5) { if (REGION_SIZE(*target) < 4 + sizeof(auth_hmd5)) return (ISC_R_NOSPACE); } else { if (REGION_SIZE(*target) < 4 + sizeof(auth_hsha)) return (ISC_R_NOSPACE); } /* * Emit protocol version. */ PUT32(1, target->rstart); if (secret != NULL) { /* * Emit _auth section with zeroed HMAC signature. * We'll replace the zeros with the real signature once * we know what it is. */ if (algorithm == ISCCC_ALG_HMACMD5) { hmac_rstart = target->rstart + HMD5_OFFSET; PUT_MEM(auth_hmd5, sizeof(auth_hmd5), target->rstart); } else { unsigned char *hmac_alg; hmac_rstart = target->rstart + HSHA_OFFSET; hmac_alg = hmac_rstart - 1; PUT_MEM(auth_hsha, sizeof(auth_hsha), target->rstart); PUT8(algorithm, hmac_alg); } } else hmac_rstart = NULL; signed_rstart = target->rstart; /* * Delete any existing _auth section so that we don't try * to encode it. */ isccc_alist_delete(alist, "_auth"); /* * Emit the message. */ result = table_towire(alist, target); if (result != ISC_R_SUCCESS) return (result); if (secret != NULL) return (sign(signed_rstart, (unsigned int)(target->rstart - signed_rstart), hmac_rstart, algorithm, secret)); return (ISC_R_SUCCESS); }
static isc_result_t value_towire(isccc_sexpr_t *elt, isccc_region_t *target) { size_t len; unsigned char *lenp; isccc_region_t *vr; isc_result_t result; if (isccc_sexpr_binaryp(elt)) { vr = isccc_sexpr_tobinary(elt); len = REGION_SIZE(*vr); if (REGION_SIZE(*target) < 1 + 4 + len) return (ISC_R_NOSPACE); PUT8(ISCCC_CCMSGTYPE_BINARYDATA, target->rstart); PUT32(len, target->rstart); if (REGION_SIZE(*target) < len) return (ISC_R_NOSPACE); PUT_MEM(vr->rstart, len, target->rstart); } else if (isccc_alist_alistp(elt)) { if (REGION_SIZE(*target) < 1 + 4) return (ISC_R_NOSPACE); PUT8(ISCCC_CCMSGTYPE_TABLE, target->rstart); /* * Emit a placeholder length. */ lenp = target->rstart; PUT32(0, target->rstart); /* * Emit the table. */ result = table_towire(elt, target); if (result != ISC_R_SUCCESS) return (result); len = (size_t)(target->rstart - lenp); /* * 'len' is 4 bytes too big, since it counts * the placeholder length too. Adjust and * emit. */ INSIST(len >= 4U); len -= 4; PUT32(len, lenp); } else if (isccc_sexpr_listp(elt)) { if (REGION_SIZE(*target) < 1 + 4) return (ISC_R_NOSPACE); PUT8(ISCCC_CCMSGTYPE_LIST, target->rstart); /* * Emit a placeholder length and count. */ lenp = target->rstart; PUT32(0, target->rstart); /* * Emit the list. */ result = list_towire(elt, target); if (result != ISC_R_SUCCESS) return (result); len = (size_t)(target->rstart - lenp); /* * 'len' is 4 bytes too big, since it counts * the placeholder length. Adjust and emit. */ INSIST(len >= 4U); len -= 4; PUT32(len, lenp); } return (ISC_R_SUCCESS); }