summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/pubkey/pubkey_cert.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/pubkey/pubkey_cert.c')
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_cert.c175
1 files changed, 79 insertions, 96 deletions
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.c b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
index 863a8a1d4..f149f6379 100644
--- a/src/libstrongswan/plugins/pubkey/pubkey_cert.c
+++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
@@ -17,11 +17,6 @@
#include <debug.h>
-/**
- * defined in pubkey_public_key.c
- */
-extern public_key_t *pubkey_public_key_load(chunk_t blob);
-
typedef struct private_pubkey_cert_t private_pubkey_cert_t;
/**
@@ -33,17 +28,22 @@ struct private_pubkey_cert_t {
* public functions
*/
pubkey_cert_t public;
-
+
/**
* wrapped public key
*/
public_key_t *key;
-
+
/**
* dummy issuer id, ID_ANY
*/
identification_t *issuer;
-
+
+ /**
+ * subject, ID_KEY_ID of the public key
+ */
+ identification_t *subject;
+
/**
* reference count
*/
@@ -63,7 +63,7 @@ static certificate_type_t get_type(private_pubkey_cert_t *this)
*/
static identification_t* get_subject(private_pubkey_cert_t *this)
{
- return this->key->get_id(this->key, ID_PUBKEY_INFO_SHA1);
+ return this->subject;
}
/**
@@ -80,14 +80,21 @@ static identification_t* get_issuer(private_pubkey_cert_t *this)
static id_match_t has_subject(private_pubkey_cert_t *this,
identification_t *subject)
{
- identification_t *id;
-
- id = this->key->get_id(this->key, subject->get_type(subject));
- if (id)
+ if (subject->get_type(subject) == ID_KEY_ID)
{
- return id->matches(id, subject);
+ key_encoding_type_t type;
+ chunk_t fingerprint;
+
+ for (type = 0; type < KEY_ENCODING_MAX; type++)
+ {
+ if (this->key->get_fingerprint(this->key, type, &fingerprint) &&
+ chunk_equals(fingerprint, subject->get_encoding(subject)))
+ {
+ return ID_MATCH_PERFECT;
+ }
+ }
}
- return ID_MATCH_NONE;
+ return ID_MATCH_NONE;
}
/**
@@ -104,15 +111,19 @@ static id_match_t has_issuer(private_pubkey_cert_t *this,
*/
static bool equals(private_pubkey_cert_t *this, certificate_t *other)
{
- if (this == (private_pubkey_cert_t*)other)
- {
- return TRUE;
- }
- if (other->get_type(other) != CERT_TRUSTED_PUBKEY)
+ public_key_t *other_key;
+
+ other_key = other->get_public_key(other);
+ if (other_key)
{
- return FALSE;
+ if (public_key_equals(this->key, other_key))
+ {
+ other_key->destroy(other_key);
+ return TRUE;
+ }
+ other_key->destroy(other_key);
}
- return other->has_subject(other, this->key->get_id(this->key, ID_PUBKEY_INFO_SHA1));
+ return FALSE;
}
/**
@@ -131,6 +142,7 @@ static public_key_t* get_public_key(private_pubkey_cert_t *this)
this->key->get_ref(this->key);
return this->key;
}
+
/**
* Implementation of certificate_t.get_validity.
*/
@@ -155,13 +167,19 @@ static bool is_newer(certificate_t *this, certificate_t *that)
{
return FALSE;
}
-
+
/**
* Implementation of certificate_t.get_encoding.
*/
static chunk_t get_encoding(private_pubkey_cert_t *this)
{
- return this->key->get_encoding(this->key);
+ chunk_t encoding;
+
+ if (this->key->get_encoding(this->key, KEY_PUB_ASN1_DER, &encoding))
+ {
+ return encoding;
+ }
+ return chunk_empty;
}
/**
@@ -180,6 +198,7 @@ static void destroy(private_pubkey_cert_t *this)
{
if (ref_put(&this->ref))
{
+ this->subject->destroy(this->subject);
this->issuer->destroy(this->issuer);
this->key->destroy(this->key);
free(this);
@@ -192,7 +211,8 @@ static void destroy(private_pubkey_cert_t *this)
static pubkey_cert_t *pubkey_cert_create(public_key_t *key)
{
private_pubkey_cert_t *this = malloc_thing(private_pubkey_cert_t);
-
+ chunk_t fingerprint;
+
this->public.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
this->public.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
this->public.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
@@ -206,97 +226,60 @@ static pubkey_cert_t *pubkey_cert_create(public_key_t *key)
this->public.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
this->public.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
this->public.interface.destroy = (void (*)(certificate_t *this))destroy;
-
+
this->ref = 1;
this->key = key;
this->issuer = identification_create_from_encoding(ID_ANY, chunk_empty);
-
- return &this->public;
-}
-
-static pubkey_cert_t *pubkey_cert_create_from_chunk(chunk_t blob)
-{
- public_key_t *key = pubkey_public_key_load(chunk_clone(blob));
+ if (key->get_fingerprint(key, KEY_ID_PUBKEY_INFO_SHA1, &fingerprint))
+ {
+ this->subject = identification_create_from_encoding(ID_KEY_ID, fingerprint);
+ }
+ else
+ {
+ this->subject = identification_create_from_encoding(ID_ANY, chunk_empty);
+ }
- return (key)? pubkey_cert_create(key) : NULL;
+ return &this->public;
}
-typedef struct private_builder_t private_builder_t;
/**
- * Builder implementation for key loading
+ * See header.
*/
-struct private_builder_t {
- /** implements the builder interface */
- builder_t public;
- /** loaded public key */
- pubkey_cert_t *key;
-};
-
-/**
- * Implementation of builder_t.build
- */
-static pubkey_cert_t *build(private_builder_t *this)
+pubkey_cert_t *pubkey_cert_wrap(certificate_type_t type, va_list args)
{
- pubkey_cert_t *key = this->key;
-
- free(this);
- return key;
-}
+ public_key_t *key = NULL;
+ chunk_t blob = chunk_empty;
-/**
- * Implementation of builder_t.add
- */
-static void add(private_builder_t *this, builder_part_t part, ...)
-{
- if (!this->key)
+ while (TRUE)
{
- va_list args;
-
- switch (part)
+ switch (va_arg(args, builder_part_t))
{
case BUILD_BLOB_ASN1_DER:
- {
- va_start(args, part);
- this->key = pubkey_cert_create_from_chunk(va_arg(args, chunk_t));
- va_end(args);
- return;
- }
+ blob = va_arg(args, chunk_t);
+ continue;
case BUILD_PUBLIC_KEY:
- {
- va_start(args, part);
- this->key = pubkey_cert_create(va_arg(args, public_key_t*));
- va_end(args);
- return;
- }
- default:
+ key = va_arg(args, public_key_t*);
+ continue;
+ case BUILD_END:
break;
+ default:
+ return NULL;
}
+ break;
}
- if (this->key)
+ if (key)
{
- destroy((private_pubkey_cert_t*)this->key);
+ key->get_ref(key);
}
- builder_cancel(&this->public);
-}
-
-/**
- * Builder construction function
- */
-builder_t *pubkey_cert_builder(certificate_type_t type)
-{
- private_builder_t *this;
-
- if (type != CERT_TRUSTED_PUBKEY)
+ else if (blob.ptr)
{
- return NULL;
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ BUILD_BLOB_ASN1_DER, blob, BUILD_END);
}
-
- this = malloc_thing(private_builder_t);
-
- this->key = NULL;
- this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
- this->public.build = (void*(*)(builder_t *this))build;
-
- return &this->public;
+ if (key)
+ {
+ return pubkey_cert_create(key);
+ }
+ return NULL;
}