static void *dnskey_validate(struct rr *rrv) { RRCAST(dnskey); if (G.opt.policy_checks[POLICY_DNSKEY]) { if (algorithm_type(rr->algorithm) == ALG_RSA_FAMILY) { unsigned int e_bytes; unsigned char *pk; int l; pk = (unsigned char *)rr->pubkey.data; l = rr->pubkey.length; e_bytes = *pk++; l--; if (e_bytes == 0) { if (l < 2) return moan(rr->rr.file_name, rr->rr.line, "public key is too short"); e_bytes = (*pk++) << 8; e_bytes += *pk++; l -= 2; } if (l < e_bytes) return moan(rr->rr.file_name, rr->rr.line, "public key is too short"); if (*pk == 0) return moan(rr->rr.file_name, rr->rr.line, "leading zero octets in public key exponent"); pk += e_bytes; l -= e_bytes; if (l > 0 && *pk == 0) return moan(rr->rr.file_name, rr->rr.line, "leading zero octets in key modulus"); } } return NULL; }
int dnskey_build_pkey(struct rr_dnskey *rr) { if (rr->pkey_built) return rr->pkey ? 1 : 0; rr->pkey_built = 1; if (algorithm_type(rr->algorithm) == ALG_RSA_FAMILY) { RSA *rsa; EVP_PKEY *pkey; unsigned int e_bytes; unsigned char *pk; int l; rsa = RSA_new(); if (!rsa) goto done; pk = (unsigned char *)rr->pubkey.data; l = rr->pubkey.length; e_bytes = *pk++; l--; if (e_bytes == 0) { if (l < 2) /* public key is too short */ goto done; e_bytes = (*pk++) << 8; e_bytes += *pk++; l -= 2; } if (l < e_bytes) /* public key is too short */ goto done; rsa->e = BN_bin2bn(pk, e_bytes, NULL); pk += e_bytes; l -= e_bytes; rsa->n = BN_bin2bn(pk, l, NULL); pkey = EVP_PKEY_new(); if (!pkey) goto done; if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto done; rr->pkey = pkey; } done: if (!rr->pkey) { moan(rr->rr.file_name, rr->rr.line, "error building pkey"); } return rr->pkey ? 1 : 0; }
int main (int argc, char **argv) { int i; set_options (argc, argv); if (exercises_executor (argc, argv)) return; instance_t instance_type = input_type (argc, argv); algorithm_t alg_type = algorithm_type (argc, argv); /* if (!feof (stdin)) TODO Not working return; */ if (instance_type == taillard) for (i = 0; i < TAILLARD_N_INSTANCES; i++) fetch_execute (stdin, instance_type, alg_type); else fetch_execute (stdin, instance_type, alg_type); destroy_options (); }
static struct rr* cert_parse(char *name, long ttl, int type, char *s) { struct rr_cert *rr = getmem(sizeof(*rr)); int cert_type, key_tag, alg; cert_type = extract_certificate_type(&s, "certificate type"); if (cert_type < 0) return NULL; rr->type = cert_type; key_tag = extract_integer(&s, "key tag"); if (key_tag < 0) return NULL; if (key_tag > 65535) return bitch("bad key tag"); rr->key_tag = key_tag; if (isdigit(*s)) { alg = extract_integer(&s, "algorithm"); if (alg < 0) return NULL; if (alg > 255) return bitch("bad algorithm"); if (alg != 0) { /* 0 is just fine */ if (algorithm_type(alg) == ALG_UNSUPPORTED) return bitch("bad algorithm %d", alg); } } else { alg = extract_algorithm(&s, "algorithm"); if (alg == ALG_UNSUPPORTED) return NULL; } rr->algorithm = alg; if (alg == 0 && key_tag != 0) { /* we might want to bitch here, but RFC says "SHOULD", so we don't */ } rr->certificate = extract_base64_binary_data(&s, "certificate"); if (rr->certificate.length < 0) return NULL; /* TODO validate cert length based on algorithm */ if (*s) { return bitch("garbage after valid CERT data"); } return store_record(type, name, ttl, rr); }
int dnskey_build_pkey(struct rr_dnskey *rr) { if (rr->pkey_built) return rr->pkey ? 1 : 0; rr->pkey_built = 1; if (algorithm_type(rr->algorithm) == ALG_RSA_FAMILY) { RSA *rsa; EVP_PKEY *pkey; unsigned int e_bytes; unsigned char *pk; int l; rsa = RSA_new(); if (!rsa) goto done; pk = (unsigned char *)rr->pubkey.data; l = rr->pubkey.length; e_bytes = *pk++; l--; if (e_bytes == 0) { if (l < 2) /* public key is too short */ goto done; e_bytes = (*pk++) << 8; e_bytes += *pk++; l -= 2; } if (l < e_bytes) /* public key is too short */ goto done; rsa->e = BN_bin2bn(pk, e_bytes, NULL); pk += e_bytes; l -= e_bytes; rsa->n = BN_bin2bn(pk, l, NULL); pkey = EVP_PKEY_new(); if (!pkey) goto done; if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto done; rr->pkey = pkey; } else if (algorithm_type(rr->algorithm) == ALG_ECC_FAMILY) { EC_KEY *pubeckey; EVP_PKEY *pkey; unsigned char *pk; int l; BIGNUM *bn_x = NULL; BIGNUM *bn_y = NULL; if (rr->algorithm == ALG_ECDSAP256SHA256) { l = SHA256_DIGEST_LENGTH; pubeckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); } else if (rr->algorithm == ALG_ECDSAP384SHA384) { l = SHA384_DIGEST_LENGTH; pubeckey = EC_KEY_new_by_curve_name(NID_secp384r1); } else { goto done; } if (!pubeckey) goto done; if (rr->pubkey.length != 2*l) { goto done; } pk = (unsigned char *)rr->pubkey.data; bn_x = BN_bin2bn(pk, l, NULL); bn_y = BN_bin2bn(&pk[l], l, NULL); if (1 != EC_KEY_set_public_key_affine_coordinates(pubeckey, bn_x, bn_y)) { goto done; } pkey = EVP_PKEY_new(); if (!pkey) goto done; if (!EVP_PKEY_assign_EC_KEY(pkey, pubeckey)) goto done; rr->pkey = pkey; } done: if (!rr->pkey) { moan(rr->rr.file_name, rr->rr.line, "error building pkey"); } return rr->pkey ? 1 : 0; }