aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/encoding
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/encoding')
-rw-r--r--src/charon/encoding/payloads/cert_payload.c132
-rw-r--r--src/charon/encoding/payloads/cert_payload.h36
2 files changed, 144 insertions, 24 deletions
diff --git a/src/charon/encoding/payloads/cert_payload.c b/src/charon/encoding/payloads/cert_payload.c
index e641cfb0e..c482b7a40 100644
--- a/src/charon/encoding/payloads/cert_payload.c
+++ b/src/charon/encoding/payloads/cert_payload.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -17,6 +18,7 @@
*/
#include <stddef.h>
+#include <ctype.h>
#include <daemon.h>
@@ -75,6 +77,11 @@ struct private_cert_payload_t {
* The contained cert data value.
*/
chunk_t data;
+
+ /**
+ * TRUE if the hash and URL data is invalid
+ */
+ bool invalid_hash_and_url;
};
/**
@@ -123,6 +130,42 @@ encoding_rule_t cert_payload_encodings[] = {
*/
static status_t verify(private_cert_payload_t *this)
{
+ if (this->encoding == ENC_X509_HASH_AND_URL ||
+ this->encoding == ENC_X509_HASH_AND_URL_BUNDLE)
+ {
+ /* rough verification of hash and URL encoded certificates */
+ if (this->data.len <= 20)
+ {
+ DBG1(DBG_ENC, "invalid payload length for hash and URL (%d), ignore",
+ this->data.len);
+ this->invalid_hash_and_url = TRUE;
+ return SUCCESS;
+ }
+
+ int i = 20; /* skipping the hash */
+ for (; i < this->data.len; ++i)
+ {
+ if (this->data.ptr[i] == '\0')
+ {
+ /* null terminated, fine */
+ return SUCCESS;
+ }
+ else if (!isprint(this->data.ptr[i]))
+ {
+ DBG1(DBG_ENC, "non printable characters in URL of hash and URL"
+ " encoded certificate payload, ignore");
+ this->invalid_hash_and_url = TRUE;
+ return SUCCESS;
+ }
+ }
+
+ /* URL is not null terminated, correct that */
+ chunk_t data = chunk_alloc(this->data.len + 1);
+ memcpy(data.ptr, this->data.ptr, this->data.len);
+ data.ptr[this->data.len] = '\0';
+ chunk_free(&this->data);
+ this->data = data;
+ }
return SUCCESS;
}
@@ -169,40 +212,59 @@ static size_t get_length(private_cert_payload_t *this)
}
/**
+ * Implementation of cert_payload_t.get_cert_encoding.
+ */
+static cert_encoding_t get_cert_encoding(private_cert_payload_t *this)
+{
+ return this->encoding;
+}
+
+/**
* Implementation of cert_payload_t.get_cert.
*/
-static certificate_t* get_cert(private_cert_payload_t *this)
+static certificate_t *get_cert(private_cert_payload_t *this)
{
- certificate_type_t type;
-
- switch (this->encoding)
+ if (this->encoding != ENC_X509_SIGNATURE)
{
- case ENC_X509_SIGNATURE:
- type = CERT_X509;
- break;
- case ENC_PKCS7_WRAPPED_X509:
- case ENC_PGP:
- case ENC_DNS_SIGNED_KEY:
- case ENC_KERBEROS_TOKEN:
- case ENC_CRL:
- case ENC_ARL:
- case ENC_SPKI:
- case ENC_X509_ATTRIBUTE:
- case ENC_RAW_RSA_KEY:
- case ENC_X509_HASH_AND_URL:
- case ENC_X509_HASH_AND_URL_BUNDLE:
- case ENC_OCSP_CONTENT:
- default:
- DBG1(DBG_ENC, "certificate encoding %N not supported",
- cert_encoding_names, this->encoding);
- return NULL;
+ return NULL;
}
- return lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
+ return lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_BLOB_ASN1_DER, chunk_clone(this->data),
BUILD_END);
}
/**
+ * Implementation of cert_payload_t.get_hash.
+ */
+static chunk_t get_hash(private_cert_payload_t *this)
+{
+ chunk_t hash = chunk_empty;
+ if ((this->encoding != ENC_X509_HASH_AND_URL &&
+ this->encoding != ENC_X509_HASH_AND_URL_BUNDLE) ||
+ this->invalid_hash_and_url)
+ {
+ return hash;
+ }
+ hash.ptr = this->data.ptr;
+ hash.len = 20;
+ return hash;
+}
+
+/**
+ * Implementation of cert_payload_t.get_url.
+ */
+static char *get_url(private_cert_payload_t *this)
+{
+ if ((this->encoding != ENC_X509_HASH_AND_URL &&
+ this->encoding != ENC_X509_HASH_AND_URL_BUNDLE) ||
+ this->invalid_hash_and_url)
+ {
+ return NULL;
+ }
+ return (char*)this->data.ptr + 20;
+}
+
+/**
* Implementation of payload_t.destroy and cert_payload_t.destroy.
*/
static void destroy(private_cert_payload_t *this)
@@ -228,12 +290,16 @@ cert_payload_t *cert_payload_create()
this->public.destroy = (void (*) (cert_payload_t*))destroy;
this->public.get_cert = (certificate_t* (*) (cert_payload_t*))get_cert;
+ this->public.get_cert_encoding = (cert_encoding_t (*) (cert_payload_t*))get_cert_encoding;
+ this->public.get_hash = (chunk_t (*) (cert_payload_t*))get_hash;
+ this->public.get_url = (char* (*) (cert_payload_t*))get_url;
this->critical = FALSE;
this->next_payload = NO_PAYLOAD;
this->payload_length = CERT_PAYLOAD_HEADER_LENGTH;
this->data = chunk_empty;
this->encoding = 0;
+ this->invalid_hash_and_url = FALSE;
return &this->public;
}
@@ -261,3 +327,21 @@ cert_payload_t *cert_payload_create_from_cert(certificate_t *cert)
return &this->public;
}
+/*
+ * Described in header
+ */
+cert_payload_t *cert_payload_create_from_hash_and_url(chunk_t hash, char *url)
+{
+ private_cert_payload_t *this = (private_cert_payload_t*)cert_payload_create();
+ chunk_t url_chunk;
+
+ this->encoding = ENC_X509_HASH_AND_URL;
+
+ url_chunk.ptr = url;
+ url_chunk.len = strlen(url) + 1;
+
+ this->data = chunk_cat("cc", hash, url_chunk);
+ this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->data.len;
+ return &this->public;
+}
+
diff --git a/src/charon/encoding/payloads/cert_payload.h b/src/charon/encoding/payloads/cert_payload.h
index 6b8228bb6..5a084cdb0 100644
--- a/src/charon/encoding/payloads/cert_payload.h
+++ b/src/charon/encoding/payloads/cert_payload.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -80,6 +81,32 @@ struct cert_payload_t {
certificate_t *(*get_cert)(cert_payload_t *this);
/**
+ * Get the encoding of the certificate.
+ *
+ * @return encoding
+ */
+ cert_encoding_t (*get_cert_encoding)(cert_payload_t *this);
+
+ /**
+ * Get the hash if this is a hash and URL encoded certificate.
+ *
+ * This function returns internal data, do not free.
+ *
+ * @return hash
+ */
+ chunk_t (*get_hash)(cert_payload_t *this);
+
+ /**
+ * Get the URL if this is a hash and URL encoded certificate.
+ *
+ * This function returns internal data, do not free.
+ *
+ * @return url
+ */
+ char *(*get_url)(cert_payload_t *this);
+
+
+ /**
* Destroys the cert_payload object.
*/
void (*destroy) (cert_payload_t *this);
@@ -101,4 +128,13 @@ cert_payload_t *cert_payload_create(void);
*/
cert_payload_t *cert_payload_create_from_cert(certificate_t *cert);
+/**
+ * Creates a certificate payload with hash and URL encoding of a certificate.
+ *
+ * @param hash hash of the DER encoded certificate (get's cloned)
+ * @param url the URL to locate the certificate (get's cloned)
+ * @return cert_payload_t object
+ */
+cert_payload_t *cert_payload_create_from_hash_and_url(chunk_t hash, char *url);
+
#endif /* CERT_PAYLOAD_H_ @} */