diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-05-15 12:46:05 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-05-15 12:46:05 +0000 |
commit | 2e324229c02ff24a2ef25fa8771d5e18533bb39c (patch) | |
tree | ef7479298dcdc0112f86720d578dfe669f98a657 /src | |
parent | b17e0db3726f4389ac3185f48e91ca6641f3ae18 (diff) | |
download | strongswan-2e324229c02ff24a2ef25fa8771d5e18533bb39c.tar.bz2 strongswan-2e324229c02ff24a2ef25fa8771d5e18533bb39c.tar.xz |
support of multiple certificates with same peer id
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/config/credentials/local_credential_store.c | 110 | ||||
-rw-r--r-- | src/charon/sa/authenticators/rsa_authenticator.c | 25 | ||||
-rwxr-xr-x | src/libstrongswan/credential_store.h | 21 |
3 files changed, 93 insertions, 63 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; diff --git a/src/charon/sa/authenticators/rsa_authenticator.c b/src/charon/sa/authenticators/rsa_authenticator.c index 19aad06bf..beb9463fb 100644 --- a/src/charon/sa/authenticators/rsa_authenticator.c +++ b/src/charon/sa/authenticators/rsa_authenticator.c @@ -60,8 +60,8 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init, { status_t status; chunk_t auth_data, octets; - rsa_public_key_t *public_key; identification_t *other_id; + ca_info_t *issuer; prf_t *prf; other_id = this->ike_sa->get_other_id(this->ike_sa); @@ -71,28 +71,17 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init, return INVALID_ARG; } auth_data = auth_payload->get_data(auth_payload); - public_key = charon->credentials->get_trusted_public_key(charon->credentials, - other_id); - if (public_key == NULL) - { - DBG1(DBG_IKE, "no RSA public key found for '%D'", other_id); - return NOT_FOUND; - } prf = this->ike_sa->get_prf(this->ike_sa); prf->set_key(prf, this->ike_sa->get_skp_verify(this->ike_sa)); octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, prf); - status = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data); + status = charon->credentials->verify_signature(charon->credentials, + octets, auth_data, other_id, &issuer); chunk_free(&octets); - if (status != SUCCESS) - { - DBG1(DBG_IKE, "RSA signature verification failed"); - return status; - } - - DBG1(DBG_IKE, "authentication of '%D' with %N successful", - other_id, auth_method_names, AUTH_RSA); - return SUCCESS; + DBG1(DBG_IKE, "authentication of '%D' with %N %s", + other_id, auth_method_names, AUTH_RSA, + (status == SUCCESS)? "successful":"failed"); + return status; } /** diff --git a/src/libstrongswan/credential_store.h b/src/libstrongswan/credential_store.h index 65e692dcd..dce8d60f7 100755 --- a/src/libstrongswan/credential_store.h +++ b/src/libstrongswan/credential_store.h @@ -88,15 +88,6 @@ struct credential_store_t { rsa_public_key_t* (*get_rsa_public_key) (credential_store_t *this, identification_t *id); /** - * @brief Returns the RSA public key of a specific ID if is trusted - * - * @param this calling object - * @param id identification_t object identifiying the key. - * @return public key, or NULL if not found or not trusted - */ - rsa_public_key_t* (*get_trusted_public_key) (credential_store_t *this, identification_t *id); - - /** * @brief Returns the RSA private key belonging to an RSA public key * * The returned rsa_private_key_t must be destroyed by the caller after usage. @@ -154,6 +145,18 @@ struct credential_store_t { ca_info_t* (*get_issuer) (credential_store_t *this, const x509_t* cert); /** + * @brief Verify an RSA signature given the ID of the signer + * + * @param this calling object + * @param hash hash value to be verified. + * @param sig signature to be verified. + * @param id identification_t object identifiying the signer. + * @param issuer_p issuer of the signer's certificate (if not self-signed). + * @return status of the verification - SUCCESS if successful + */ + status_t (*verify_signature) (credential_store_t *this, chunk_t hash, chunk_t sig, identification_t *id, ca_info_t **issuer_p); + + /** * @brief Verify an X.509 certificate up to trust anchor without any status checks * * @param this calling object |