aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/config
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2007-05-15 12:46:05 +0000
committerAndreas Steffen <andreas.steffen@strongswan.org>2007-05-15 12:46:05 +0000
commit2e324229c02ff24a2ef25fa8771d5e18533bb39c (patch)
treeef7479298dcdc0112f86720d578dfe669f98a657 /src/charon/config
parentb17e0db3726f4389ac3185f48e91ca6641f3ae18 (diff)
downloadstrongswan-2e324229c02ff24a2ef25fa8771d5e18533bb39c.tar.bz2
strongswan-2e324229c02ff24a2ef25fa8771d5e18533bb39c.tar.xz
support of multiple certificates with same peer id
Diffstat (limited to 'src/charon/config')
-rw-r--r--src/charon/config/credentials/local_credential_store.c110
1 files changed, 74 insertions, 36 deletions
diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c
index a920150ac..e21c28af9 100644
--- a/src/charon/config/credentials/local_credential_store.c
+++ b/src/charon/config/credentials/local_credential_store.c
@@ -323,51 +323,89 @@ static ca_info_t* get_issuer(private_local_credential_store_t *this, const x509_
}
/**
- * Implementation of local_credential_store_t.get_trusted_public_key.
+ * Implementation of local_credential_store_t.verify.
*/
-static rsa_public_key_t *get_trusted_public_key(private_local_credential_store_t *this,
- identification_t *id)
+static status_t verify_signature(private_local_credential_store_t *this,
+ chunk_t hash, chunk_t sig,
+ identification_t *id, ca_info_t **issuer_p)
{
- cert_status_t status;
- err_t ugh;
-
- x509_t *cert = get_certificate(this, id);
+ iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
+ status_t sig_status;
+ x509_t *cert;
- if (cert == NULL)
- return NULL;
+ /* default return values in case of failure */
+ sig_status = NOT_FOUND;
+ *issuer_p = NULL;
- ugh = cert->is_valid(cert, NULL);
- if (ugh != NULL)
+ while (iterator->iterate(iterator, (void**)&cert))
{
- DBG1(DBG_CFG, "certificate %s", ugh);
- return NULL;
- }
+ if (id->equals(id, cert->get_subject(cert))
+ || cert->equals_subjectAltName(cert, id))
+ {
+ err_t ugh;
+ rsa_public_key_t *public_key = cert->get_public_key(cert);
+ chunk_t keyid = public_key->get_keyid(public_key);
- if (!cert->is_self_signed(cert))
- {
- ca_info_t *issuer = get_issuer(this, cert);
+ DBG2(DBG_CFG, "found candidate peer certificate");
+ DBG2(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
+ DBG2(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
+ DBG2(DBG_CFG, "keyid: %#B", &keyid);
- if (issuer == NULL)
- {
- DBG1(DBG_CFG, "issuer of public key not found");
- return NULL;
- }
- status = cert->get_status(cert);
+ ugh = cert->is_valid(cert, NULL);
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "candidate peer certificate %s", ugh);
+ sig_status = INVALID_STATE;
+ continue;
+ }
+ if (!cert->is_self_signed(cert))
+ {
+ cert_status_t cert_status;
+ ca_info_t *issuer = get_issuer(this, cert);
- if (status == CERT_REVOKED
- || status == CERT_UNTRUSTED
- || (issuer->is_strict(issuer) && status != CERT_GOOD))
- {
- DBG1(DBG_CFG, "certificate status: %N", cert_status_names, status);
- return NULL;
- }
- if (status == CERT_GOOD && cert->get_until(cert) < time(NULL))
- {
- DBG1(DBG_CFG, "certificate is good but crl is stale");
- return NULL;
+ if (issuer == NULL)
+ {
+ DBG1(DBG_CFG, "issuer of candidate peer certificate not found");
+ sig_status = NOT_FOUND;
+ continue;
+ }
+ cert_status = cert->get_status(cert);
+
+ if (cert_status == CERT_REVOKED
+ || cert_status == CERT_UNTRUSTED
+ || ((issuer)->is_strict(issuer) && cert_status != CERT_GOOD))
+ {
+ DBG1(DBG_CFG, "candidate peer certificate has a non-acceptable status: %N", cert_status_names, cert_status);
+ sig_status = INVALID_STATE;
+ continue;
+ }
+ if (cert_status == CERT_GOOD && cert->get_until(cert) < time(NULL))
+ {
+ DBG1(DBG_CFG, "candidate peer certificate is good but crl is stale");
+ sig_status = INVALID_STATE;
+ continue;
+ }
+ *issuer_p = issuer;
+ }
+ sig_status = public_key->verify_emsa_pkcs1_signature(public_key, hash, sig);
+ if (sig_status == SUCCESS)
+ {
+ DBG2(DBG_CFG, "candidate peer certificate has a matching RSA public key");
+ break;
+ }
+ else
+ {
+ DBG1(DBG_CFG, "candidate peer certificate has a non-matching RSA public key");
+ *issuer_p = NULL;
+ }
}
}
- return cert->get_public_key(cert);
+ iterator->destroy(iterator);
+ if (sig_status == NOT_FOUND)
+ {
+ DBG1(DBG_CFG, "no candidate peer certificate found");
+ }
+ return sig_status;
}
/**
@@ -1414,12 +1452,12 @@ local_credential_store_t * local_credential_store_create(void)
this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
this->public.credential_store.get_rsa_private_key = (rsa_private_key_t* (*) (credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
- this->public.credential_store.get_trusted_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_trusted_public_key;
this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
this->public.credential_store.get_auth_certificate = (x509_t* (*) (credential_store_t*,u_int,identification_t*))get_auth_certificate;
this->public.credential_store.get_ca_certificate_by_keyid = (x509_t* (*) (credential_store_t*,chunk_t))get_ca_certificate_by_keyid;
this->public.credential_store.get_issuer = (ca_info_t* (*) (credential_store_t*,const x509_t*))get_issuer;
this->public.credential_store.is_trusted = (bool (*) (credential_store_t*,x509_t*))is_trusted;
+ this->public.credential_store.verify_signature = (status_t (*) (credential_store_t*,chunk_t,chunk_t,identification_t*,ca_info_t**))verify_signature;
this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
this->public.credential_store.add_auth_certificate = (x509_t* (*) (credential_store_t*,x509_t*,u_int))add_auth_certificate;