config setup
conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
keyexchange=ikev1
conn rw
left=PH_IP_MOON
leftcert=moonCert.pem
leftid=@moon.strongswan.org
leftsubnet=10.1.0.0/16
leftfirewall=yes
# right=%any
right=PH_IP_SUN
rightid=@sun.strongswan.org
rightsubnet=10.1.0.0/16
auto=add
config setup
conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
keyexchange=ikev1
conn home
left=PH_IP_SUN
leftcert=sunCert.pem
leftid=@sun.strongswan.org
leftsubnet=10.1.0.0/16
leftfirewall=yes
right=PH_IP_MOON
rightid=@moon.strongswan.org
rightsubnet=10.1.0.0/16
auto=add
/**
* Build certificate requests
*/
static void build_certreqs(private_isakmp_cert_pre_t *this, message_t *message)
{
enumerator_t *enumerator;
ike_cfg_t *ike_cfg;
peer_cfg_t *peer_cfg;
certificate_t *cert;
auth_cfg_t *auth;
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
if (!ike_cfg->send_certreq(ike_cfg))
{
return;
}
/* check if we require a specific CA for that peer */
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
if (peer_cfg)
{ /*默认的配置里,我们没有指定新的CA,因此不会走到add_certreqs的流程 */
enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, FALSE);
if (enumerator->enumerate(enumerator, &auth))
{
add_certreqs(this, auth, message);
}
enumerator->destroy(enumerator);
}
if (!message->get_payload(message, PLV1_CERTREQ))
{
/* otherwise add all trusted CA certificates */
enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
CERT_ANY, KEY_ANY, NULL, TRUE);
while (enumerator->enumerate(enumerator, &cert))
{ /* 遍历了lib->credmgr的sets链表,去找所有证书,在add_certreq里会判断,只会添加CA证书,并且加入的是证书的subject */
add_certreq(this, message, cert);
}
enumerator->destroy(enumerator);
}
}
static void process_certreqs(private_isakmp_cert_pre_t *this, message_t *message)
{
enumerator_t *enumerator;
payload_t *payload;
auth_cfg_t *auth;
auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);/* 注意,这里找到ike_sa->my_auth,注意,此时auth->entries里面的元素是空的 */
enumerator = message->create_payload_enumerator(message);
while (enumerator->enumerate(enumerator, &payload))
{
switch (payload->get_type(payload))
{
case PLV1_CERTREQ:
{
certificate_t *cert;
this->ike_sa->set_condition(this->ike_sa,
COND_CERTREQ_SEEN, TRUE);
cert = find_certificate(this, (certreq_payload_t*)payload); /* 根据证书载荷找到CA证书 */
if (cert)
{ /* 找到了,那么把CA证书保存到ike_sa->my_auth->entries中 */
auth->add(auth, AUTH_RULE_CA_CERT, cert);
}
break;
}
default:
break;
}
}
enumerator->destroy(enumerator);
}
case MM_KE:
{
id_payload_t *id_payload;
identification_t *id;
id = this->ph1->get_id(this->ph1, this->peer_cfg, TRUE);
if (!id)
{
DBG1(DBG_CFG, "own identity not known");
return send_notify(this, INVALID_ID_INFORMATION);
}
this->ike_sa->set_my_id(this->ike_sa, id->clone(id));/* 保存自己的ID moon.strongswan.cn 到ike_sa->my_id中,之前my_id为空 */
id_payload = id_payload_create_from_identification(PLV1_ID, id);
message->add_payload(message, &id_payload->payload_interface);
if (!this->ph1->build_auth(this->ph1, this->method, message, /* 构造SIG载荷 */
id_payload->get_encoded(id_payload)))
{
return send_notify(this, AUTHENTICATION_FAILED);
}
add_initial_contact(this, message, id);
this->state = MM_AUTH;
return NEED_MORE;
}
METHOD(credential_manager_t, get_private, private_key_t*,
private_credential_manager_t *this, key_type_t type, identification_t *id,
auth_cfg_t *auth)
{
enumerator_t *enumerator;
certificate_t *cert;
private_key_t *private = NULL;
auth_cfg_t *trustchain;
auth_rule_t rule;
/* check if this is a lookup by key ID, and do it if so */
if (id && id->get_type(id) == ID_KEY_ID) /* M_I_5里type为KEY_RSA,因此不会走到这 */
{
private = get_private_by_keyid(this, type, id);
if (private)
{
return private;
}
}
if (auth)
{ /* M_I_5里auth虽然不为空,首次来的时候,里面只有CA的证书 *//* 在M_I_1中,get_auth_method会走到这里 */
/* try to find a trustchain with one of the configured subject certs */
enumerator = auth->create_enumerator(auth);
while (enumerator->enumerate(enumerator, &rule, &cert))
{
if (rule == AUTH_RULE_SUBJECT_CERT)
{ /* get_auth_method里传下来的auth是配置里的auth,是有本地证书的,*/
private = get_private_by_cert(this, cert, type);
if (private)
{
trustchain = build_trustchain(this, cert, auth);
if (trustchain)
{
auth->merge(auth, trustchain, FALSE);
prefer_cert(auth, cert->get_ref(cert));
trustchain->destroy(trustchain);
break;
}
private->destroy(private);
private = NULL;
}
}
}
enumerator->destroy(enumerator);
if (private)
{
return private;
}
/* M_I_5里,首次找也是没有的 */
/* if none yielded a trustchain, enforce the first configured cert */
cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
if (cert)
{
private = get_private_by_cert(this, cert, type);
if (private)
{
trustchain = build_trustchain(this, cert, auth);
if (trustchain)
{
auth->merge(auth, trustchain, FALSE);
trustchain->destroy(trustchain);
}
return private;
}
}
/* try to build a trust chain for each certificate found */
enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
while (enumerator->enumerate(enumerator, &cert))
{ /* 通过ID找到本地证书 */
private = get_private_by_cert(this, cert, type);/* 找私钥 */
if (private)
{ /* 构造证书信任链 */
trustchain = build_trustchain(this, cert, auth);
if (trustchain)
{
auth->merge(auth, trustchain, FALSE);
trustchain->destroy(trustchain);
break;
}
private->destroy(private);
private = NULL;
}
}
enumerator->destroy(enumerator);
}
/* if no valid trustchain was found, fall back to the first usable cert */
if (!private)
{
enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
while (enumerator->enumerate(enumerator, &cert))
{
private = get_private_by_cert(this, cert, type);
if (private)
{
if (auth)
{
auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert->get_ref(cert));
}
break;
}
}
enumerator->destroy(enumerator);
}
return private;
}
/**
* find a private key of a given certificate
*/
static private_key_t *get_private_by_cert(private_credential_manager_t *this,
certificate_t *cert, key_type_t type)
{
private_key_t *private = NULL;
identification_t *keyid;
chunk_t chunk;
public_key_t *public;
public = cert->get_public_key(cert);
if (public)
{ /* 这里的私钥,是通过指纹匹配的,指纹之前配置时就生成好的 */
if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &chunk))
{
keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
private = get_private_by_keyid(this, type, keyid);
keyid->destroy(keyid);
}
public->destroy(public);
}
return private;
}
/**
* build a trustchain from subject up to a trust anchor in trusted
*/
static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
certificate_t *subject, auth_cfg_t *auth)
{
certificate_t *issuer, *current;
auth_cfg_t *trustchain;
int pathlen = 0;
bool has_anchor;
trustchain = auth_cfg_create();
has_anchor = auth->get(auth, AUTH_RULE_CA_CERT) != NULL; /* ike_sa的auth传进来的时候已经有本地CA了,配置auth传下来没有 */
current = subject->get_ref(subject);
while (TRUE)
{ /* auth_contans_cacert是要判断auth里是否有CA证书,且CA证书和currrent是同一个证书 */
if (auth_contains_cacert(auth, current)) /* 第一次current为要认证的证书,这里为假,第二次为第一次的签发者,以此类推 */
{
trustchain->add(trustchain, AUTH_RULE_CA_CERT, current);
return trustchain;
}
if (subject == current)
{ /* 第一次是相等的 ,因此会把本地证书加到信任链中 */
trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT, current);
}
else
{
if (!has_anchor && issued_by(this, current, current, NULL))/* 如果没有指定根CA,那么此时又自认证成功,那么认为成功 */
{ /* If no trust anchor specified, accept any CA */
trustchain->add(trustchain, AUTH_RULE_CA_CERT, current);
return trustchain;
}
trustchain->add(trustchain, AUTH_RULE_IM_CERT, current);
}
if (pathlen++ > MAX_TRUST_PATH_LEN) /* 证书链的层次 */
{
break;
}
issuer = get_issuer_cert(this, current, FALSE, NULL);/* 找本证书的签发者 */
if (!issuer)
{
if (!has_anchor)
{ /* If no trust anchor specified, accept incomplete chains */
return trustchain;
}
break;
}
if (has_anchor && issuer->equals(issuer, current))/* 如果指定了根CA,去比较最终的签发者 */
{
issuer->destroy(issuer);
break;
}
current = issuer;
}
trustchain->destroy(trustchain);
return NULL;
}
case MM_KE:
{
id_payload_t *id_payload;
identification_t *id;
id_payload = (id_payload_t*)message->get_payload(message, PLV1_ID);
if (!id_payload)
{
DBG1(DBG_IKE, "IDii payload missing");
return send_notify(this, INVALID_PAYLOAD_TYPE);
}
id = id_payload->get_identification(id_payload);
this->ike_sa->set_other_id(this->ike_sa, id);
while (TRUE)
{
DESTROY_IF(this->peer_cfg);
this->peer_cfg = this->ph1->select_config(this->ph1,
this->method, FALSE, id);
if (!this->peer_cfg)
{
return send_notify(this, AUTHENTICATION_FAILED);
}
this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
if (this->ph1->verify_auth(this->ph1, this->method, message,
id_payload->get_encoded(id_payload)))
{
break;
}
}
if (!charon->bus->authorize(charon->bus, FALSE))
{
DBG1(DBG_IKE, "Main Mode authorization hook forbids IKE_SA, "
"cancelling");
return send_notify(this, AUTHENTICATION_FAILED);
}
this->state = MM_AUTH;
if (has_notify_errors(this, message))
{
return FAILED;
}
return NEED_MORE;
}
sig = sig_payload->get_hash(sig_payload);
auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, this->type,
id, auth);
while (enumerator->enumerate(enumerator, &public, ¤t_auth))
{
if (public->verify(public, scheme, hash, sig))
{
DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
id, key_type_names, this->type);
status = SUCCESS;
auth->merge(auth, current_auth, FALSE);
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
break;
}
else
{
DBG1(DBG_IKE, "signature validation failed, looking for another key");
status = FAILED;
}
}
enumerator->destroy(enumerator);