/* * Parse PKCS#7 wrapped X.509 certificates */ static bool parse_pkcs7_signedData(chunk_t blob, int level0, x509cert_t **cert) { asn1_ctx_t ctx; chunk_t object; u_int level; u_int objectID = 0; asn1_init(&ctx, blob, level0, FALSE, DBG_RAW); while (objectID < PKCS7_SIGNED_ROOF) { if (!extract_object(signedDataObjects, &objectID, &object, &level, &ctx)) return FALSE; if (objectID == PKCS7_SIGNED_CERT) { chunk_t cert_blob; x509cert_t *newcert = alloc_thing(x509cert_t, "pkcs7 wrapped x509cert"); clonetochunk(cert_blob, object.ptr, object.len, "pkcs7 cert blob"); *newcert = empty_x509cert; if (parse_x509cert(cert_blob, level + 1, newcert)) { newcert->next = *cert; *cert = newcert; } else { free_x509cert(newcert); } } objectID++; } return TRUE; }
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); } } }