------------------------------------------------------------ revno: 5274 committer: Henrik Ziegeldorf <henrik.ziegeldorf@xxxxxxxxxxxxxx> branch nick: ecc timestamp: Sat 2011-01-08 14:46:38 +0100 message: Refactored key loader functions and function parse_hit() in rule_management.c, which alone calls these functions. Changes - Caller of key loader function gets control over memory management. - RSA_new, DSA_new and EC_KEY_new are not necessary because PEM_read_xxx_PUBKEY handles this. - Do not allocate memory for calls to xxx_to_dns_key_rr(..) because these functions handle the memory allocation themselves. In fact this should be refactored, too. - Improved error handling for key loader functions. - Improved debugging output of parse_hit(). - Updated documentation. modified: firewall/rule_management.c -- lp:~hipl-core/hipl/ecc https://code.launchpad.net/~hipl-core/hipl/ecc Your team HIPL core team is subscribed to branch lp:~hipl-core/hipl/ecc. To unsubscribe from this branch go to https://code.launchpad.net/~hipl-core/hipl/ecc/+edit-subscription
=== modified file 'firewall/rule_management.c' --- firewall/rule_management.c 2011-01-08 12:25:47 +0000 +++ firewall/rule_management.c 2011-01-08 13:46:38 +0000 @@ -379,92 +379,100 @@ return option; } + /** * Load an RSA public key from a file and convert it into a hip_host_id. * - * @param fp FILE object from where to load a PEM formatted RSA public key + * @param fp FILE object from where to load a PEM formatted RSA public key + * @param hi the key is returned inside this host identity struct * - * @return hip_host id structure (caller deallocates) or NULL on error + * @return 0 on success, negative on error */ -static struct hip_host_id *load_rsa_file(FILE *fp) +static int load_rsa_file(FILE *fp, struct hip_host_id *hi) { - struct hip_host_id *hi = NULL; - RSA *rsa = NULL; - unsigned char *rsa_key_rr = NULL; + int err = 0; + RSA *rsa = NULL; + unsigned char *rsa_key_rr = NULL; int rsa_key_rr_len; - rsa = RSA_new(); - rsa = PEM_read_RSA_PUBKEY(fp, &rsa, NULL, NULL); - if (!rsa) { - HIP_DEBUG("reading RSA file failed \n"); - RSA_free(rsa); - return NULL; - } - rsa_key_rr = malloc(sizeof(struct hip_host_id)); - rsa_key_rr_len = rsa_to_dns_key_rr(rsa, &rsa_key_rr); - hi = malloc(sizeof(struct hip_host_id)); + HIP_IFEL(!hi, -1, "Cannot write return value, because passed hi is NULL\n"); + + HIP_IFEL(!(rsa = PEM_read_RSA_PUBKEY(fp, &rsa, NULL, NULL)), + -1, "Reading DSA key failed (maybe key is not in PEM format?)\n"); + HIP_IFEL((rsa_key_rr_len = rsa_to_dns_key_rr(rsa, &rsa_key_rr)) < 0, + -1, "Serialization of DSA key failed \n"); + + // no error checking here, since both functions are void hip_build_param_host_id_hdr(hi, NULL, rsa_key_rr_len, HIP_HI_RSA); hip_build_param_host_id_only(hi, rsa_key_rr, NULL); - return hi; +out_err: + if (err) { + RSA_free(rsa); + free(rsa_key_rr); + } + return err; } /** * Load an DSA public key from a file and convert it into a hip_host_id. * - * @param fp FILE object from where to load a PEM formatted DSA public key + * @param fp FILE object from where to load a PEM formatted DSA public key + * @param hi the key is returned inside this host identity struct * - * @return hip_host id structure (caller deallocates) or NULL on error + * @return 0 on success, negative on error */ -static struct hip_host_id *load_dsa_file(FILE *fp) +static int load_dsa_file(FILE *fp, struct hip_host_id *hi) { - struct hip_host_id *hi = NULL; - DSA *dsa = NULL; - unsigned char *dsa_key_rr = NULL; + int err = 0; + DSA *dsa = NULL; + unsigned char *dsa_key_rr = NULL; int dsa_key_rr_len; - dsa = DSA_new(); - dsa = PEM_read_DSA_PUBKEY(fp, &dsa, NULL, NULL); - if (!dsa) { - HIP_DEBUG("reading DSA file failed \n"); - DSA_free(dsa); - return NULL; - } - dsa_key_rr = malloc(sizeof(struct hip_host_id)); - dsa_key_rr_len = dsa_to_dns_key_rr(dsa, &dsa_key_rr); - hi = malloc(sizeof(struct hip_host_id)); + HIP_IFEL(!hi, -1, "Cannot write return value, because passed hi is NULL\n"); + + HIP_IFEL(!(dsa = PEM_read_DSA_PUBKEY(fp, &dsa, NULL, NULL)), + -1, "Reading DSA key failed (maybe key is not in PEM format?)\n"); + HIP_IFEL((dsa_key_rr_len = dsa_to_dns_key_rr(dsa, &dsa_key_rr)) < 0, + -1, "Serialization of DSA key failed \n"); + + // no error checking here, since both functions are void hip_build_param_host_id_hdr(hi, NULL, dsa_key_rr_len, HIP_HI_DSA); hip_build_param_host_id_only(hi, dsa_key_rr, NULL); - return hi; + +out_err: + if (err) { + DSA_free(dsa); + free(dsa_key_rr); + } + return err; } /** * Load an ECDSA public key from a file and convert it into a hip_host_id. * - * @param fp FILE object from where to load a PEM formatted ECDSA public key + * @param fp FILE object from where to load a PEM formatted ECDSA public key + * @param hi the key is returned inside this host identity struct * - * @return hip_host id structure (caller deallocates) or NULL on error + * @return 0 on success, negative on error */ -static struct hip_host_id *load_ecdsa_file(FILE *fp) +static int load_ecdsa_file(FILE *fp, struct hip_host_id *hi) { int err = 0; - struct hip_host_id *hi = NULL; EC_KEY *ecdsa = NULL; unsigned char *ecdsa_key_rr = NULL; int ecdsa_key_rr_len; - ecdsa = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL); - if (!ecdsa) { - HIP_DEBUG("reading ECDSA file failed \n"); - err = -1; - goto out_err; - } - HIP_IFEL(!(ecdsa_key_rr = malloc(sizeof(struct hip_host_id))), + HIP_IFEL(!hi, -1, "Cannot write return value, because passed hi is NULL\n"); + + HIP_IFEL(!(ecdsa = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL)), + -1, "Reading ECDSA key failed (maybe key is not in PEM format?)\n"); + HIP_IFEL(!(ecdsa_key_rr = malloc(sizeof(struct hip_host_id))), -ENOMEM, "Could not allocate memory for ecdsa_key_rr\n"); - ecdsa_key_rr_len = ecdsa_to_key_rr(ecdsa, &ecdsa_key_rr); - HIP_IFEL(!(hi = malloc(sizeof(struct hip_host_id))), - -ENOMEM, "Could not allocat memory for host identity.\n"); + HIP_IFEL((ecdsa_key_rr_len = ecdsa_to_key_rr(ecdsa, &ecdsa_key_rr)) < 0, + -1, "Serialization of ECDSA key failed \n"); + // no error checking here, since both functions are void hip_build_param_host_id_hdr(hi, NULL, ecdsa_key_rr_len, HIP_HI_ECDSA); hip_build_param_host_id_only(hi, ecdsa_key_rr, NULL); @@ -472,10 +480,8 @@ if (err) { EC_KEY_free(ecdsa); free(ecdsa_key_rr); - free(hi); - return NULL; } - return hi; + return err; } /** @@ -487,8 +493,9 @@ * @return a hip_host_id structure which the caller must deallocate * @note token file name must have _dsa_ or _rsa_ in the file to distinguish the algorithm */ -static struct hip_host_id *parse_hi(char *token, const struct in6_addr *hit) +static struct hip_host_id *parse_hi(const char *token, const struct in6_addr *hit) { + int err = 0; FILE *fp = NULL; int algo; struct hip_host_id *hi = NULL; @@ -510,23 +517,29 @@ HIP_DEBUG("Invalid filename for HI: missing _rsa_ or _dsa_ \n"); return NULL; } + + HIP_IFEL(!(hi = malloc(sizeof(struct hip_host_id))), + -1, "Could not allocate memory for host identity\n"); if (algo == HIP_HI_RSA) { - hi = load_rsa_file(fp); + HIP_IFEL(load_rsa_file(fp, hi), -1, "Failed to load RSA key\n"); } else if (algo == HIP_HI_ECDSA) { - hi = load_ecdsa_file(fp); + HIP_IFEL(load_ecdsa_file(fp, hi), -1, "Failed to load ECDSA key\n") } else { - hi = load_dsa_file(fp); - } - if (!hi) { - HIP_DEBUG("file loading failed \n"); - return NULL; + HIP_IFEL(load_dsa_file(fp, hi), -1, "Failed to load DSA key\n") } /* verify hi => hit */ hip_host_id_to_hit(hi, &temp_hit, HIP_HIT_TYPE_HASH100); if (ipv6_addr_cmp(&temp_hit, hit)) { - HIP_DEBUG("HI in file %s does not match hit %s \n", - token, addr_to_numeric(hit)); + err = -1; + HIP_DEBUG("HI in file %s does not match hit from rule: \n", token); + HIP_DEBUG_HIT("expected hit:\t", hit); + HIP_DEBUG_HIT("got hit:\t\t", hit); + goto out_err; + } + +out_err: + if (err) { free(hi); return NULL; }