int ca_getreq(struct iked *env, struct imsg *imsg) { struct ca_store *store = env->sc_priv; struct iked_sahdr sh; uint8_t type; uint8_t *ptr; size_t len; unsigned int i, n; X509 *ca = NULL, *cert = NULL; struct ibuf *buf; struct iked_static_id id; ptr = (uint8_t *)imsg->data; len = IMSG_DATA_SIZE(imsg); i = sizeof(id) + sizeof(uint8_t) + sizeof(sh); if (len < i || ((len - i) % SHA_DIGEST_LENGTH) != 0) return (-1); memcpy(&id, ptr, sizeof(id)); if (id.id_type == IKEV2_ID_NONE) return (-1); memcpy(&sh, ptr + sizeof(id), sizeof(sh)); memcpy(&type, ptr + sizeof(id) + sizeof(sh), sizeof(uint8_t)); switch (type) { case IKEV2_CERT_RSA_KEY: if (store->ca_pubkey.id_type != type || (buf = store->ca_pubkey.id_buf) == NULL) return (-1); log_debug("%s: using local public key of type %s", __func__, print_map(type, ikev2_cert_map)); break; case IKEV2_CERT_X509_CERT: for (n = 1; i < len; n++, i += SHA_DIGEST_LENGTH) { if ((ca = ca_by_subjectpubkey(store->ca_cas, ptr + i, SHA_DIGEST_LENGTH)) == NULL) continue; log_debug("%s: found CA %s", __func__, ca->name); if ((cert = ca_by_issuer(store->ca_certs, X509_get_subject_name(ca), &id)) != NULL) { /* XXX * should we re-validate our own cert here? */ break; } } if (ca == NULL || cert == NULL) { log_warnx("%s: no valid local certificate found", __func__); type = IKEV2_CERT_NONE; ca_setcert(env, &sh, NULL, type, NULL, 0, PROC_IKEV2); return (0); } log_debug("%s: found local certificate %s", __func__, cert->name); if ((buf = ca_x509_serialize(cert)) == NULL) return (-1); break; default: log_warnx("%s: unknown cert type requested", __func__); return (-1); } ca_setcert(env, &sh, NULL, type, ibuf_data(buf), ibuf_size(buf), PROC_IKEV2); return (0); }
int ca_getreq(struct iked *env, struct imsg *imsg) { struct ca_store *store = env->sc_priv; struct iked_sahdr sh; u_int8_t type; u_int8_t *ptr; size_t len; u_int i, n; X509 *ca = NULL, *cert = NULL; struct ibuf *buf; struct iked_static_id id; ptr = (u_int8_t *)imsg->data; len = IMSG_DATA_SIZE(imsg); i = sizeof(id) + sizeof(u_int8_t) + sizeof(sh); if (len < i || ((len - i) % SHA_DIGEST_LENGTH) != 0) return (-1); memcpy(&id, ptr, sizeof(id)); if (id.id_type == IKEV2_ID_NONE) return (-1); memcpy(&sh, ptr + sizeof(id), sizeof(sh)); memcpy(&type, ptr + sizeof(id) + sizeof(sh), sizeof(u_int8_t)); if (type != IKEV2_CERT_X509_CERT) return (-1); for (n = 1; i < len; n++, i += SHA_DIGEST_LENGTH) { if ((ca = ca_by_subjectpubkey(store->ca_cas, ptr + i, SHA_DIGEST_LENGTH)) == NULL) { log_debug("%s: CA %d not found", __func__, n); print_hex(ptr, i, SHA_DIGEST_LENGTH); continue; } log_debug("%s: found CA %s", __func__, ca->name); if ((cert = ca_by_issuer(store->ca_certs, X509_get_subject_name(ca), &id)) != NULL) { /* XXX should we re-validate our own cert here? */ break; } log_debug("%s: no valid certificate for this CA", __func__); } if (ca == NULL || cert == NULL) { log_warnx("%s: no valid local certificate found", __func__); type = IKEV2_CERT_NONE; ca_setcert(env, &sh, NULL, type, NULL, 0, PROC_IKEV2); return (0); } log_debug("%s: found local certificate %s", __func__, cert->name); if ((buf = ca_x509_serialize(cert)) == NULL) return (-1); type = IKEV2_CERT_X509_CERT; ca_setcert(env, &sh, NULL, type, ibuf_data(buf), ibuf_size(buf), PROC_IKEV2); return (0); }