diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2007-10-26 14:10:02 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2007-10-26 14:10:02 +0000 |
commit | 49104abddf3d71d5abf5cf75dc7f95fa6c55fa63 (patch) | |
tree | 28f7a72e5dec4abf908fd7874bdab776281310bc /src/charon/config/credentials/local_credential_store.c | |
parent | 7b0305f59ddab9ea026b202a8c569912e5bf9a90 (diff) | |
download | vyos-strongswan-49104abddf3d71d5abf5cf75dc7f95fa6c55fa63.tar.gz vyos-strongswan-49104abddf3d71d5abf5cf75dc7f95fa6c55fa63.zip |
[svn-upgrade] Integrating new upstream version, strongswan (4.1.8)
Diffstat (limited to 'src/charon/config/credentials/local_credential_store.c')
-rw-r--r-- | src/charon/config/credentials/local_credential_store.c | 249 |
1 files changed, 184 insertions, 65 deletions
diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c index 649fcbcfb..b71e9e9e2 100644 --- a/src/charon/config/credentials/local_credential_store.c +++ b/src/charon/config/credentials/local_credential_store.c @@ -66,7 +66,7 @@ struct shared_key_t { static void shared_key_destroy(shared_key_t *this) { this->peers->destroy_offset(this->peers, offsetof(identification_t, destroy)); - chunk_free(&this->secret); + chunk_free_randomized(&this->secret); free(this); } @@ -83,7 +83,7 @@ static shared_key_t *shared_key_create(chunk_t secret) shared_key_t *this = malloc_thing(shared_key_t); /* private data */ - this->secret = chunk_clone(secret); + this->secret = secret; this->peers = linked_list_create(); return (this); @@ -158,6 +158,11 @@ struct private_local_credential_store_t { linked_list_t *private_keys; /** + * mutex controls access to the linked lists of secret keys + */ + pthread_mutex_t keys_mutex; + + /** * list of X.509 certificates with public keys */ linked_list_t *certs; @@ -171,6 +176,16 @@ struct private_local_credential_store_t { * list of X.509 CA information records */ linked_list_t *ca_infos; + + /** + * list of X.509 attribute certificates + */ + linked_list_t *acerts; + + /** + * mutex controls access to the linked list of attribute certificates + */ + pthread_mutex_t acerts_mutex; }; @@ -191,8 +206,9 @@ static status_t get_key(linked_list_t *keys, prio_t best_prio = PRIO_UNDEFINED; chunk_t found = chunk_empty; shared_key_t *shared_key; + iterator_t *iterator; - iterator_t *iterator = keys->create_iterator(keys, TRUE); + iterator = keys->create_iterator(keys, TRUE); while (iterator->iterate(iterator, (void**)&shared_key)) { @@ -242,7 +258,6 @@ static status_t get_key(linked_list_t *keys, } } - /** * Implementation of local_credential_store_t.get_shared_key. */ @@ -250,7 +265,12 @@ static status_t get_shared_key(private_local_credential_store_t *this, identification_t *my_id, identification_t *other_id, chunk_t *secret) { - return get_key(this->shared_keys, my_id, other_id, secret); + status_t status; + + pthread_mutex_lock(&(this->keys_mutex)); + status = get_key(this->shared_keys, my_id, other_id, secret); + pthread_mutex_unlock(&(this->keys_mutex)); + return status; } /** @@ -260,7 +280,12 @@ static status_t get_eap_key(private_local_credential_store_t *this, identification_t *my_id, identification_t *other_id, chunk_t *secret) { - return get_key(this->eap_keys, my_id, other_id, secret); + status_t status; + + pthread_mutex_lock(&(this->keys_mutex)); + status = get_key(this->eap_keys, my_id, other_id, secret); + pthread_mutex_unlock(&(this->keys_mutex)); + return status; } /** @@ -325,36 +350,16 @@ static ca_info_t* get_issuer(private_local_credential_store_t *this, x509_t *cer } /** - * Implementation of local_credential_store_t.get_rsa_private_key. - */ -static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *this, - rsa_public_key_t *pubkey) -{ - rsa_private_key_t *found = NULL, *current; - - iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE); - - while (iterator->iterate(iterator, (void**)¤t)) - { - if (current->belongs_to(current, pubkey)) - { - found = current->clone(current); - break; - } - } - iterator->destroy(iterator); - return found; -} - -/** * Implementation of local_credential_store_t.has_rsa_private_key. */ static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_public_key_t *pubkey) { bool found = FALSE; rsa_private_key_t *current; + iterator_t *iterator; - iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE); + pthread_mutex_lock(&(this->keys_mutex)); + iterator = this->private_keys->create_iterator(this->private_keys, TRUE); while (iterator->iterate(iterator, (void**)¤t)) { @@ -365,6 +370,7 @@ static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_publ } } iterator->destroy(iterator); + pthread_mutex_unlock(&(this->keys_mutex)); return found; } @@ -725,10 +731,51 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f } /** + * Implementation of local_credential_store_t.rsa_signature. + */ +static status_t rsa_signature(private_local_credential_store_t *this, + rsa_public_key_t *pubkey, + hash_algorithm_t hash_algorithm, + chunk_t data, chunk_t *signature) +{ + rsa_private_key_t *current, *key = NULL; + iterator_t *iterator; + status_t status; + chunk_t keyid = pubkey->get_keyid(pubkey); + + DBG2(DBG_IKE, "looking for RSA private key with keyid %#B...", &keyid); + pthread_mutex_lock(&(this->keys_mutex)); + + iterator = this->private_keys->create_iterator(this->private_keys, TRUE); + while (iterator->iterate(iterator, (void**)¤t)) + { + if (current->belongs_to(current, pubkey)) + { + key = current; + break; + } + } + iterator->destroy(iterator); + + if (key) + { + DBG2(DBG_IKE, " matching RSA private key found"); + status = key->build_emsa_pkcs1_signature(key, hash_algorithm, data, signature); + } + else + { + DBG1(DBG_IKE, "no RSA private key found with keyid %#B", &keyid); + status = NOT_FOUND; + } + pthread_mutex_unlock(&(this->keys_mutex)); + return status; +} + +/** * Implementation of local_credential_store_t.verify_signature. */ static status_t verify_signature(private_local_credential_store_t *this, - chunk_t hash, chunk_t sig, + chunk_t hash, chunk_t signature, identification_t *id, ca_info_t **issuer_p) { iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE); @@ -785,7 +832,7 @@ static status_t verify_signature(private_local_credential_store_t *this, } *issuer_p = issuer; } - sig_status = public_key->verify_emsa_pkcs1_signature(public_key, hash, sig); + sig_status = public_key->verify_emsa_pkcs1_signature(public_key, HASH_UNKNOWN, hash, signature); if (sig_status == SUCCESS) { DBG2(DBG_CFG, "candidate peer certificate has a matching RSA public key"); @@ -938,6 +985,14 @@ static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this } /** + * Implements local_credential_store_t.create_acert_iterator + */ +static iterator_t* create_acert_iterator(private_local_credential_store_t *this) +{ + return this->acerts->create_iterator_locked(this->acerts, &this->acerts_mutex); +} + +/** * Implements local_credential_store_t.load_auth_certificates */ static void load_auth_certificates(private_local_credential_store_t *this, @@ -1053,7 +1108,39 @@ static void load_aa_certificates(private_local_credential_store_t *this) */ static void add_attr_certificate(private_local_credential_store_t *this, x509ac_t *cert) { - /* TODO add a new attribute certificate to the linked list */ + iterator_t *iterator; + x509ac_t *current_cert; + bool found = FALSE; + + pthread_mutex_lock(&(this->acerts_mutex)); + iterator = this->acerts->create_iterator(this->acerts, TRUE); + + while (iterator->iterate(iterator, (void **)¤t_cert)) + { + if (cert->equals_holder(cert, current_cert)) + { + if (cert->is_newer(cert, current_cert)) + { + iterator->replace(iterator, NULL, (void *)cert); + current_cert->destroy(current_cert); + DBG1(DBG_CFG, " this attr cert is newer - existing attr cert replaced"); + } + else + { + cert->destroy(cert); + DBG1(DBG_CFG, " this attr cert is not newer - existing attr cert retained"); + } + found = TRUE; + break; + } + } + iterator->destroy(iterator); + + if (!found) + { + this->acerts->insert_last(this->acerts, (void *)cert); + } + pthread_mutex_unlock(&(this->acerts_mutex)); } /** @@ -1230,21 +1317,26 @@ static err_t extract_secret(chunk_t *secret, chunk_t *line) } if (quotes) - { /* treat as an ASCII string */ - if (raw_secret.len > secret->len) - return "secret larger than buffer"; - memcpy(secret->ptr, raw_secret.ptr, raw_secret.len); - secret->len = raw_secret.len; + { + /* treat as an ASCII string */ + *secret = chunk_clone(raw_secret); } else - { /* convert from HEX or Base64 to binary */ + { size_t len; - err_t ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len); + err_t ugh; + + /* secret converted to binary form doesn't use more space than the raw_secret */ + *secret = chunk_alloc(raw_secret.len); + + /* convert from HEX or Base64 to binary */ + ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len); if (ugh != NULL) + { + chunk_free_randomized(secret); return ugh; - if (len > secret->len) - return "secret larger than buffer"; + } secret->len = len; } return NULL; @@ -1253,17 +1345,18 @@ static err_t extract_secret(chunk_t *secret, chunk_t *line) /** * Implements local_credential_store_t.load_secrets */ -static void load_secrets(private_local_credential_store_t *this) +static void load_secrets(private_local_credential_store_t *this, bool reload) { FILE *fd = fopen(SECRETS_FILE, "r"); if (fd) { - int bytes; + size_t bytes; int line_nr = 0; chunk_t chunk, src, line; - DBG1(DBG_CFG, "loading secrets from \"%s\"", SECRETS_FILE); + DBG1(DBG_CFG, "%sloading secrets from \"%s\"", + reload? "re":"", SECRETS_FILE); fseek(fd, 0, SEEK_END); chunk.len = ftell(fd); @@ -1271,9 +1364,25 @@ static void load_secrets(private_local_credential_store_t *this) chunk.ptr = malloc(chunk.len); bytes = fread(chunk.ptr, 1, chunk.len, fd); fclose(fd); - src = chunk; + pthread_mutex_lock(&(this->keys_mutex)); + if (reload) + { + DBG1(DBG_CFG, " forgetting old secrets"); + this->private_keys->destroy_offset(this->private_keys, + offsetof(rsa_private_key_t, destroy)); + this->private_keys = linked_list_create(); + + this->shared_keys->destroy_function(this->shared_keys, + (void*)shared_key_destroy); + this->shared_keys = linked_list_create(); + + this->eap_keys->destroy_function(this->eap_keys, + (void*)shared_key_destroy); + this->eap_keys = linked_list_create(); + } + while (fetchline(&src, &line)) { chunk_t ids, token; @@ -1302,9 +1411,7 @@ static void load_secrets(private_local_credential_store_t *this) { char path[PATH_BUF]; chunk_t filename; - - char buf[BUF_LEN]; - chunk_t secret = { buf, BUF_LEN }; + chunk_t secret = chunk_empty; chunk_t *passphrase = NULL; rsa_private_key_t *key; @@ -1350,14 +1457,13 @@ static void load_secrets(private_local_credential_store_t *this) { this->private_keys->insert_last(this->private_keys, (void*)key); } + chunk_free_randomized(&secret); } else if ( match("PSK", &token) || ((match("EAP", &token) || match("XAUTH", &token)) && (is_eap = TRUE))) { shared_key_t *shared_key; - - char buf[BUF_LEN]; - chunk_t secret = { buf, BUF_LEN }; + chunk_t secret = chunk_empty; err_t ugh = extract_secret(&secret, &line); if (ugh != NULL) @@ -1373,16 +1479,13 @@ static void load_secrets(private_local_credential_store_t *this) DBG4(DBG_CFG, " secret:", secret); shared_key = shared_key_create(secret); - if (shared_key) + if (is_eap) { - if (is_eap) - { - this->eap_keys->insert_last(this->eap_keys, (void*)shared_key); - } - else - { - this->shared_keys->insert_last(this->shared_keys, (void*)shared_key); - } + this->eap_keys->insert_last(this->eap_keys, (void*)shared_key); + } + else + { + this->shared_keys->insert_last(this->shared_keys, (void*)shared_key); } while (ids.len > 0) { @@ -1430,7 +1533,8 @@ static void load_secrets(private_local_credential_store_t *this) } } error: - free(chunk.ptr); + chunk_free_randomized(&chunk); + pthread_mutex_unlock(&(this->keys_mutex)); } else { @@ -1447,9 +1551,17 @@ static void destroy(private_local_credential_store_t *this) this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy)); this->auth_certs->destroy_offset(this->auth_certs, offsetof(x509_t, destroy)); this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy)); + + pthread_mutex_lock(&(this->acerts_mutex)); + this->acerts->destroy_offset(this->acerts, offsetof(x509ac_t, destroy)); + pthread_mutex_unlock(&(this->acerts_mutex)); + + pthread_mutex_lock(&(this->keys_mutex)); this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy)); this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy); this->eap_keys->destroy_function(this->eap_keys, (void*)shared_key_destroy); + pthread_mutex_unlock(&(this->keys_mutex)); + free(this); } @@ -1459,17 +1571,18 @@ static void destroy(private_local_credential_store_t *this) local_credential_store_t * local_credential_store_create(void) { private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t); - + + /* public functions */ this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key; this->public.credential_store.get_eap_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_eap_key; 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_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*,x509_t*))get_issuer; this->public.credential_store.is_trusted = (bool (*) (credential_store_t*,const char*,x509_t*))is_trusted; + this->public.credential_store.rsa_signature = (status_t (*) (credential_store_t*,rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t*))rsa_signature; 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; @@ -1479,14 +1592,19 @@ local_credential_store_t * local_credential_store_create(void) this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator; this->public.credential_store.create_auth_cert_iterator = (iterator_t* (*) (credential_store_t*))create_auth_cert_iterator; this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator; + this->public.credential_store.create_acert_iterator = (iterator_t* (*) (credential_store_t*))create_acert_iterator; this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates; this->public.credential_store.load_aa_certificates = (void (*) (credential_store_t*))load_aa_certificates; this->public.credential_store.load_attr_certificates = (void (*) (credential_store_t*))load_attr_certificates; this->public.credential_store.load_ocsp_certificates = (void (*) (credential_store_t*))load_ocsp_certificates; this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls; - this->public.credential_store.load_secrets = (void (*) (credential_store_t*))load_secrets; + this->public.credential_store.load_secrets = (void (*) (credential_store_t*,bool))load_secrets; this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy; - + + /* initialize the mutexes */ + pthread_mutex_init(&(this->keys_mutex), NULL); + pthread_mutex_init(&(this->acerts_mutex), NULL); + /* private variables */ this->shared_keys = linked_list_create(); this->eap_keys = linked_list_create(); @@ -1494,6 +1612,7 @@ local_credential_store_t * local_credential_store_create(void) this->certs = linked_list_create(); this->auth_certs = linked_list_create(); this->ca_infos = linked_list_create(); + this->acerts = linked_list_create(); return (&this->public); } |