int ds_sha384_hash_is_equal(u_char * name_n, u_char * rrdata, size_t rrdatalen, u_char * ds_hash, size_t ds_hash_len) { u_char ds_digest[SHA384_DIGEST_LENGTH]; size_t namelen; SHA512_CTX c; size_t l_index; u_char qc_name_n[NS_MAXCDNAME]; if (rrdata == NULL || ds_hash_len != SHA384_DIGEST_LENGTH) return 0; namelen = wire_name_length(name_n); memcpy(qc_name_n, name_n, namelen); l_index = 0; lower_name(qc_name_n, &l_index); memset(ds_digest, 0, SHA384_DIGEST_LENGTH); SHA384_Init(&c); SHA384_Update(&c, qc_name_n, namelen); SHA384_Update(&c, rrdata, rrdatalen); SHA384_Final(ds_digest, &c); if (!memcmp(ds_digest, ds_hash, SHA384_DIGEST_LENGTH)) return 1; return 0; }
u_char * nsec3_sha_hash_compute(u_char * name_n, u_char * salt, size_t saltlen, size_t iter, u_char ** hash, size_t * hashlen) { /* * Assume that the caller has already performed all sanity checks */ SHA_CTX c; size_t i; size_t l_index; int len = wire_name_length(name_n); u_char qc_name_n[NS_MAXCDNAME]; memcpy(qc_name_n, name_n, len); l_index = 0; lower_name(qc_name_n, &l_index); *hash = (u_char *) MALLOC(SHA_DIGEST_LENGTH * sizeof(u_char)); if (*hash == NULL) return NULL; *hashlen = SHA_DIGEST_LENGTH; memset(*hash, 0, SHA_DIGEST_LENGTH); /* * IH(salt, x, 0) = H( x || salt) */ SHA1_Init(&c); SHA1_Update(&c, qc_name_n, wire_name_length(qc_name_n)); SHA1_Update(&c, salt, saltlen); SHA1_Final(*hash, &c); /* * IH(salt, x, k) = H(IH(salt, x, k-1) || salt) */ for (i = 0; i < iter; i++) { SHA1_Init(&c); SHA1_Update(&c, *hash, *hashlen); SHA1_Update(&c, salt, saltlen); SHA1_Final(*hash, &c); } return *hash; }
/* * Create the buffer over which the signature is to be verified */ static int make_sigfield(u_char ** field, size_t * field_length, struct rrset_rec *rr_set, struct rrset_rr *rr_sig, int is_a_wildcard) { struct rrset_rr *curr_rr; size_t index; size_t signer_length; size_t owner_length; u_int16_t type_n; u_int16_t class_n; u_int32_t ttl_n; u_int16_t rdata_length_n; u_char lowered_owner_n[NS_MAXCDNAME]; size_t l_index; int retval; if ((field == NULL) || (field_length == NULL) || (rr_set == NULL) || (rr_sig == NULL) || (rr_set->rrs_name_n == NULL) || (rr_set->rrs_sig == NULL) || (rr_set->rrs_sig->rr_rdata == NULL)) return VAL_BAD_ARGUMENT; if ((retval = predict_sigbuflength(rr_set, field_length, &signer_length)) != VAL_NO_ERROR) return retval; *field = (u_char *) MALLOC(*field_length * sizeof(u_char)); if (*field == NULL) return VAL_OUT_OF_MEMORY; /* * Make sure we are using the correct TTL */ memcpy(&ttl_n, &rr_sig->rr_rdata[TTL], sizeof(u_int32_t)); rr_set->rrs_ttl_h = ntohl(ttl_n); /* * While we're at it, we'll gather other common info, specifically * network ordered numbers (type, class) and name length. */ owner_length = wire_name_length(rr_set->rrs_name_n); if (owner_length == 0) goto err; memcpy(lowered_owner_n, rr_set->rrs_name_n, owner_length); l_index = 0; lower_name(lowered_owner_n, &l_index); type_n = htons(rr_set->rrs_type_h); class_n = htons(rr_set->rrs_class_h); /* * Copy in the SIG RDATA (up to the signature */ index = 0; if ((index + SIGNBY + signer_length) > *field_length) goto err; memcpy(&(*field)[index], rr_sig->rr_rdata, SIGNBY + signer_length); l_index = 0; lower_name(&(*field)[index+SIGNBY], &l_index); index += SIGNBY + signer_length; /* * For each record of data, copy in the envelope & the lower cased rdata */ for (curr_rr = rr_set->rrs_data; curr_rr; curr_rr = curr_rr->rr_next) { if (curr_rr->rr_rdata == NULL) goto err; /* * Copy in the envelope information */ if (is_a_wildcard) { /* * Construct the original name */ u_char wcard_n[NS_MAXCDNAME]; u_char *np = lowered_owner_n; int i; size_t outer_len; for (i = 0; i < is_a_wildcard; i++) np += np[0] + 1; outer_len = wire_name_length(np); wcard_n[0] = (u_char) 1; wcard_n[1] = '*'; if ((outer_len + 2) > sizeof(wcard_n)) goto err; memcpy(&wcard_n[2], np, outer_len); if ((index + outer_len + 2) > *field_length) goto err; memcpy(&(*field)[index], wcard_n, outer_len + 2); index += outer_len + 2; } else { if ((index + owner_length) > *field_length) goto err; memcpy(&(*field)[index], lowered_owner_n, owner_length); index += owner_length; } if ((index + sizeof(u_int16_t) + sizeof(u_int16_t) + sizeof(u_int32_t)) > *field_length) goto err; memcpy(&(*field)[index], &type_n, sizeof(u_int16_t)); index += sizeof(u_int16_t); memcpy(&(*field)[index], &class_n, sizeof(u_int16_t)); index += sizeof(u_int16_t); memcpy(&(*field)[index], &ttl_n, sizeof(u_int32_t)); index += sizeof(u_int32_t); /* * Now the RR-specific info, the length and the data */ rdata_length_n = htons(curr_rr->rr_rdata_length); if ((index + sizeof(u_int16_t) + curr_rr->rr_rdata_length) > *field_length) goto err; memcpy(&(*field)[index], &rdata_length_n, sizeof(u_int16_t)); index += sizeof(u_int16_t); memcpy(&(*field)[index], curr_rr->rr_rdata, curr_rr->rr_rdata_length); index += curr_rr->rr_rdata_length; } *field_length = index; return VAL_NO_ERROR; err: FREE(*field); *field = NULL; *field_length = 0; return VAL_BAD_ARGUMENT; }