void ikev2_decode_cert(struct msg_digest *md) { struct payload_digest *p; for (p = md->chain[ISAKMP_NEXT_v2CERT]; p != NULL; p = p->next) { struct ikev2_cert *const v2cert = &p->payload.v2cert; chunk_t blob; time_t valid_until; blob.ptr = p->pbs.cur; blob.len = pbs_left(&p->pbs); if (v2cert->isac_enc == CERT_X509_SIGNATURE) { x509cert_t cert2 = empty_x509cert; if (parse_x509cert(blob, 0, &cert2)) { if (verify_x509cert(&cert2, strict_crl_policy, &valid_until)) { DBG(DBG_X509 | DBG_PARSING, DBG_log("Public key validated") ) add_x509_public_key(NULL, &cert2, valid_until, DAL_SIGNED); } else { plog("X.509 certificate rejected"); } free_generalNames(cert2.subjectAltName, FALSE); free_generalNames(cert2.crlDistributionPoints, FALSE); } else plog("Syntax error in X.509 certificate"); } else if (v2cert->isac_enc == CERT_PKCS7_WRAPPED_X509) { x509cert_t *cert2 = NULL; if (parse_pkcs7_cert(blob, &cert2)) store_x509certs(&cert2, strict_crl_policy); else plog("Syntax error in PKCS#7 wrapped X.509 certificates"); } else { loglog(RC_LOG_SERIOUS, "ignoring %s certificate payload", enum_show(&ikev2_cert_type_names, v2cert->isac_enc)); DBG_cond_dump_chunk(DBG_PARSING, "CERT:\n", blob); } } }
/* accept_KE * * Check and accept DH public value (Gi or Gr) from peer's message. * According to RFC2409 "The Internet key exchange (IKE)" 5: * The Diffie-Hellman public value passed in a KE payload, in either * a phase 1 or phase 2 exchange, MUST be the length of the negotiated * Diffie-Hellman group enforced, if necessary, by pre-pending the * value with zeros. */ notification_t accept_KE(chunk_t *dest, const char *val_name, const struct oakley_group_desc *gr, pb_stream *pbs) { if (pbs_left(pbs) != gr->bytes) { loglog(RC_LOG_SERIOUS, "KE has %u byte DH public value; %u required", (unsigned) pbs_left(pbs), (unsigned) gr->bytes); /* XXX Could send notification back */ return INVALID_KEY_INFORMATION; } clonereplacechunk(*dest, pbs->cur, pbs_left(pbs), val_name); DBG_cond_dump_chunk(DBG_CRYPT, "DH public value received:\n", *dest); return NOTHING_WRONG; }
/* * Decode the CR payload of Phase 1. */ void decode_cr(struct msg_digest *md, generalName_t **requested_ca) { struct payload_digest *p; for (p = md->chain[ISAKMP_NEXT_CR]; p != NULL; p = p->next) { struct isakmp_cr *const cr = &p->payload.cr; chunk_t ca_name; ca_name.len = pbs_left(&p->pbs); ca_name.ptr = (ca_name.len > 0)? p->pbs.cur : NULL; DBG_cond_dump_chunk(DBG_PARSING, "CR", ca_name); if (cr->isacr_type == CERT_X509_SIGNATURE) { if (ca_name.len > 0) { generalName_t *gn; if (!is_asn1(ca_name)) continue; gn = alloc_thing(generalName_t, "generalName"); clonetochunk(ca_name, ca_name.ptr,ca_name.len, "ca name"); gn->kind = GN_DIRECTORY_NAME; gn->name = ca_name; gn->next = *requested_ca; *requested_ca = gn; } DBG(DBG_PARSING | DBG_CONTROL, char buf[IDTOA_BUF]; dntoa_or_null(buf, IDTOA_BUF, ca_name, "%any"); DBG_log("requested CA: '%s'", buf); ) } else loglog(RC_LOG_SERIOUS, "ignoring %s certificate request payload", enum_show(&cert_type_names, cr->isacr_type)); }