X-Git-Url: https://git.strongswan.org/?p=strongswan.git;a=blobdiff_plain;f=src%2Ffrontends%2Fandroid%2Fjni%2Flibandroidbridge%2Fbackend%2Fandroid_creds.c;h=ddc032638e12eba74ac82a8a4237a7550bf3dfcf;hp=ee9549d9c62908f150b35d1a86213466ee2a2665;hb=79af70c66ee2c66e985d49a84b2fe04eb329000b;hpb=8430e54d83e71b8cc806e12274905b6d0ea10f0c;ds=sidebyside diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_creds.c b/src/frontends/android/jni/libandroidbridge/backend/android_creds.c index ee9549d..ddc0326 100644 --- a/src/frontends/android/jni/libandroidbridge/backend/android_creds.c +++ b/src/frontends/android/jni/libandroidbridge/backend/android_creds.c @@ -34,7 +34,7 @@ struct private_android_creds_t { android_creds_t public; /** - * Credential set storing trusted certificates + * Credential set storing trusted certificates and user credentials */ mem_cred_t *creds; @@ -50,6 +50,15 @@ struct private_android_creds_t { }; /** + * Free allocated DER encoding + */ +static void free_encoding(chunk_t *chunk) +{ + chunk_free(chunk); + free(chunk); +} + +/** * Load trusted certificates via charonservice (JNI). */ static void load_trusted_certificates(private_android_creds_t *this) @@ -71,8 +80,7 @@ static void load_trusted_certificates(private_android_creds_t *this) cert->get_subject(cert)); this->creds->add_cert(this->creds, TRUE, cert); } - chunk_free(current); - free(current); + free_encoding(current); } certs->destroy(certs); } @@ -84,7 +92,7 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, { enumerator_t *enumerator; - if (!trusted || (cert != CERT_ANY && cert != CERT_X509)) + if (cert != CERT_ANY && cert != CERT_X509) { return NULL; } @@ -108,6 +116,99 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, this->lock); } +METHOD(android_creds_t, add_username_password, void, + private_android_creds_t *this, char *username, char *password) +{ + shared_key_t *shared_key; + identification_t *id; + chunk_t secret; + + secret = chunk_create(password, strlen(password)); + shared_key = shared_key_create(SHARED_EAP, chunk_clone(secret)); + id = identification_create_from_string(username); + + this->creds->add_shared(this->creds, shared_key, id, NULL); +} + +METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, + private_android_creds_t *this, shared_key_type_t type, + identification_t *me, identification_t *other) +{ + return this->creds->set.create_shared_enumerator(&this->creds->set, + type, me, other); +} + +METHOD(android_creds_t, load_user_certificate, certificate_t*, + private_android_creds_t *this) +{ + linked_list_t *encodings; + certificate_t *cert = NULL, *ca_cert; + chunk_t *current; + + encodings = charonservice->get_user_certificate(charonservice); + if (!encodings) + { + return NULL; + } + + while (encodings->remove_first(encodings, (void**)¤t) == SUCCESS) + { + if (!cert) + { /* the first element is the user certificate */ + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_BLOB_ASN1_DER, *current, BUILD_END); + if (!cert) + { + DBG1(DBG_CFG, "failed to load user certificate"); + free_encoding(current); + break; + } + DBG1(DBG_CFG, "loaded user certificate '%Y' and private key", + cert->get_subject(cert)); + cert = this->creds->add_cert_ref(this->creds, TRUE, cert); + free_encoding(current); + continue; + } + /* the rest are CA certificates, we ignore failures */ + ca_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_BLOB_ASN1_DER, *current, BUILD_END); + if (ca_cert) + { + DBG1(DBG_CFG, "loaded CA certificate '%Y'", + ca_cert->get_subject(ca_cert)); + this->creds->add_cert(this->creds, TRUE, ca_cert); + } + free_encoding(current); + } + encodings->destroy_function(encodings, (void*)free_encoding); + + if (cert) + { + private_key_t *key; + + key = charonservice->get_user_key(charonservice, + cert->get_public_key(cert)); + if (key) + { + this->creds->add_key(this->creds, key); + } + else + { + DBG1(DBG_CFG, "failed to load private key"); + cert->destroy(cert); + cert = NULL; + } + } + return cert; +} + +METHOD(credential_set_t, create_private_enumerator, enumerator_t*, + private_android_creds_t *this, key_type_t type, identification_t *id) +{ + return this->creds->set.create_private_enumerator(&this->creds->set, + type, id); +} + METHOD(android_creds_t, clear, void, private_android_creds_t *this) { @@ -137,11 +238,13 @@ android_creds_t *android_creds_create() .public = { .set = { .create_cert_enumerator = _create_cert_enumerator, - .create_shared_enumerator = (void*)return_null, - .create_private_enumerator = (void*)return_null, + .create_shared_enumerator = _create_shared_enumerator, + .create_private_enumerator = _create_private_enumerator, .create_cdp_enumerator = (void*)return_null, .cache_cert = (void*)nop, }, + .add_username_password = _add_username_password, + .load_user_certificate = _load_user_certificate, .clear = _clear, .destroy = _destroy, },